# Kwery — Price Data API

Real-time price data across major European and global marketplaces.

New here? Start with the **[Guides](https://kwery.co/developers/docs)** — getting started,
authentication, webhooks, and per-source field reference.

## Source and key reference

Each source supports a fixed set of `key` types. The `key` field
determines what goes in `values`.

| Source | Key | Values format | Supported countries |
|--------|-----|---------------|---------------------|
| `idealo` | `term` | Free-text search | de at uk (gb) fr it es |
| `idealo` | `id` | Idealo product ID (numeric) | de at uk (gb) fr it es |
| `idealo` | `gtin` | EAN / GTIN-13 | de at uk (gb) fr it es |
| `idealo` | `pzn` | Pharmacy product number | de |
| `amazon` | `term` | Free-text search | us ca mx br uk (gb) de at ch es fr it jp cn in ae au nl se pl be sg tr |
| `amazon` | `asin` | Amazon ASIN (10 chars) | us ca mx br uk (gb) de at ch es fr it jp cn in ae au nl se pl be sg tr |
| `amazon` | `gtin` | EAN / GTIN-13 | us ca mx br uk (gb) de at ch es fr it jp cn in ae au nl se pl be sg tr |
| `google` | `term` | Free-text search | us de uk (gb) au at br ca cz dk fr in ie it jp mx no pl nz nl ru sg za es se fi ch tr ar cl co be gr hu pt ro sk hk id il my ph sa kr tw th ua vn ae |
| `google` | `id` | Google Shopping product ID | us de uk (gb) au at br ca cz dk fr in ie it jp mx no pl nz nl ru sg za es se fi ch tr ar cl co be gr hu pt ro sk hk id il my ph sa kr tw th ua vn ae |
| `google` | `product` | Pipe-separated product record — see `GoogleProductValue` | us de uk (gb) au at br ca cz dk fr in ie it jp mx no pl nz nl ru sg za es se fi ch tr ar cl co be gr hu pt ro sk hk id il my ph sa kr tw th ua vn ae |
| `ebay` | `term` | Free-text search | au at be ca fr de ie it hk my nl pl sg es ch uk (gb) us |
| `ebay` | `id` | eBay item ID (numeric) | au at be ca fr de ie it hk my nl pl sg es ch uk (gb) us |
| `ebay` | `gtin` | EAN / GTIN-13 | au at be ca fr de ie it hk my nl pl sg es ch uk (gb) us |
| `kaufland` | `term` | Free-text search | de cz sk pl at fr it |
| `kaufland` | `id` | Kaufland product ID | de cz sk pl at fr it |
| `kaufland` | `gtin` | EAN / GTIN-13 | de cz sk pl at fr it |
| `otto` | `term` | Free-text search | de |
| `otto` | `id` | Otto product ID | de |
| `billiger` | `term` | Free-text search | de |
| `billiger` | `id` | billiger.de product ID | de |
| `billiger` | `gtin` | EAN / GTIN-13 | de |
| `guenstiger` | `term` | Free-text search | de |
| `guenstiger` | `id` | guenstiger.de product ID (numeric) | de |
| `guenstiger` | `gtin` | EAN / GTIN-13 | de |
| `walmart` | `term` | Free-text search | us |
| `walmart` | `id` | Walmart item ID | us |
| `walmart` | `gtin` | EAN / UPC / GTIN | us |
| `lidl` | `term` | Free-text search | de |
| `lidl` | `id` | Lidl product ID | de |
| `aliexpress` | `term` | Free-text search | us |
| `aliexpress` | `id` | AliExpress product ID | us |
| `rakuten` | `term` | Free-text search | jp |
| `rakuten` | `id` | Rakuten item ID | jp |

> `uk (gb)` means `uk` and `gb` are two codes for the **same** UK marketplace —
> pass either one, it is not a separate locale. For Amazon, `at` and `ch` are
> served from the amazon.de storefront with Austria/Switzerland localization.

## Authentication

Sign up at [kwery.co](https://kwery.co); the dashboard issues your API key. Send it on
every data-API request as either:
- **Bearer** — `Authorization: Bearer kwy_live_...`
- **API key header** — `x-api-key: kwy_live_...`

Legacy/enterprise accounts provisioned before self-serve may still use HTTP Basic
(username + password) or a Bearer JWT issued directly by us. See
[Authentication](authentication.md) for details.

Access is controlled per `source.country` pair. A `not subscribed to source`
error means your account is not provisioned for the requested combination.

## Response envelope

Validation errors return **HTTP 200** with `"error": true`. Always check the
`error` field before consuming a response:

```json
{ "error": true, "message": "country not supported by source" }
```

Infrastructure errors (auth, 5xx) use standard HTTP status codes.

## Stream API

For large batches (up to **100 000 values**), use the Stream endpoint.
Results are pushed to your `callback_url` as they complete — no polling needed.

1. `POST /stream` — submit values with a `callback_url`
2. Results arrive at `callback_url` in batches as they complete
3. `GET /stream/{id}` — optional progress check

## Batch API

For standard batches (up to **1 000 values**), use the Batch endpoint.
Results are retained for **72 hours**.

1. `POST /job` — submit a list of values, receive a job ID
2. `GET /job/{id}` — poll until `status` is `finished`
3. `GET /job/{id}/download` — retrieve structured results


Version: 4.0
License: Proprietary

## Servers

Production
```
https://api.kwery.co
```

## Security

### BearerAuth

JWT issued by your account. Valid for 24 hours.

Type: http
Scheme: bearer
Bearer Format: JWT

### BasicAuth

HTTP Basic authentication with your account username and password.

Type: http
Scheme: basic

### DashboardAuth

kwery.co dashboard session token (Supabase). Used by the dashboard UI
for account/keys/billing endpoints.


Type: http
Scheme: bearer
Bearer Format: JWT

### ApiKeyAuth

Your data-API key, format `kwy_live_…`. May also be sent as
`Authorization: Bearer kwy_live_…`.


Type: apiKey
In: header
Name: x-api-key

## Download OpenAPI description

[Kwery — Price Data API](https://docs.kwery.co/_bundle/openapi.yaml)

## stream

Large-scale crawls with incremental webhook delivery. Supports up to
**100 000 values** per job. Results are pushed to your endpoint as they
complete — no polling required.


### Submit a stream job

 - [POST /stream](https://docs.kwery.co/openapi/stream/submitstreamjob.md): Submit a large batch for incremental webhook delivery. Results are
pushed to callback_url in batches as they complete.

## Webhook payload

json
{
  "job_id": "...",
  "client_ref": "...",
  "batch_sequence": 1,
  "is_final": false,
  "results": [ ... ]
}


## Signature verification

Each delivery is signed with HMAC-SHA256. Verify using the
webhook_secret returned at submission:


X-Signature: sha256=


Compute HMAC-SHA256(webhook_secret, raw_request_body) and compare.

## Fallback

If webhook delivery fails after all retries, use POST /stream/{id}/replay-all
to re-queue dead-lettered deliveries, or retrieve results directly via
GET /stream/{id}/results.

## Limits

| Parameter | Default | Maximum |
|-----------|---------|---------|
| values | — | 100 000 |
| delivery_batch_size | 100 | 200 |
| Job timeout | 1 440 min | 1 440 min |

### Stream job status

 - [GET /stream/{id}](https://docs.kwery.co/openapi/stream/getstreamjob.md): Returns progress counters for a stream job. Poll to track completion
without consuming webhook deliveries.

### Poll stream results

 - [GET /stream/{id}/results](https://docs.kwery.co/openapi/stream/getstreamresults.md): Retrieve completed results without relying on webhook delivery.
Useful as a fallback or when callback_url was not provided.

Offset/limit — page through results in completion order.

Batch lookup — request a specific webhook delivery batch by
sequence number (useful for reconciling against webhook history).
When batch is provided, offset and limit are ignored.

### Replay dead-lettered deliveries

 - [POST /stream/{id}/replay-all](https://docs.kwery.co/openapi/stream/replayalldeliveries.md): Re-enqueues all dead_lettered webhook deliveries for this job.
Use after fixing a webhook endpoint that was temporarily unreachable.

### List webhook delivery history

 - [GET /stream/{id}/deliveries](https://docs.kwery.co/openapi/stream/listdeliveries.md): Returns the last 200 webhook delivery attempts for this job, newest first.
Useful for diagnosing delivery failures.

### Replay a single delivery

 - [POST /stream/deliveries/{delivery_id}/replay](https://docs.kwery.co/openapi/stream/replaysingledelivery.md): Re-enqueues a single dead_lettered delivery. Use when only
specific batches need to be retried.

## jobs

Standard batches up to **1 000 values**. Poll for results, then download.
Results are retained for **72 hours**.


### Submit a batch job

 - [POST /job](https://docs.kwery.co/openapi/jobs/submitjob.md): Submit a list of values to crawl. Returns immediately with a job
object; results are assembled asynchronously.

The request schema is discriminated on source. Select the source tab
below to see the valid key, topic, and country values for that source.

### Poll job status

 - [GET /job/{id}](https://docs.kwery.co/openapi/jobs/getjob.md): Returns current status and progress counters.

Status lifecycle: new → working → finished (or failed)

When status is finished, use GET /job/{id}/download to retrieve results.

### Update an interval job

 - [PUT /job/{id}](https://docs.kwery.co/openapi/jobs/updatejob.md): Replaces the value list and parameters of an existing interval job.
All previous results for this job are cleared.

Only the fields listed in JobUpdateRequest can be updated.
Omitted fields retain their current values.

### Delete an interval job

 - [DELETE /job/{id}](https://docs.kwery.co/openapi/jobs/deletejob.md): Permanently deletes a job and all its results. Only interval jobs
can be deleted via this endpoint.

### Download results

 - [GET /job/{id}/download](https://docs.kwery.co/openapi/jobs/downloadjob.md): Returns the complete result set for a finished job.

Results are cached after the first download; subsequent requests are
served from cache regardless of result size.

Append .csv to the URL or pass ?format=csv to receive a CSV file.

> Results are retained for 72 hours from job creation.

