Submit data to staging with an intake key. This API does not publish directly to live data and does not use your tenant's read or write key.
1. Get an intake key
A Stockisto operator issues a key with api:intake, bound to your tenant and one source: scraper, delegated or crowd. Send it in X-API-Key. Keep it in a server-side secret store; it is shown once. Keys with api:read or api:write cannot use intake, and an intake key cannot read the tenant API.
The envelope's source and any provenance.source on a record must match the key's binding. Expired, revoked and unknown keys return 401.
2. Submit a batch
Replace the placeholders and use the source bound to your key. This request writes to staging; run it only with a key issued for your source.
curl -X POST https://api.test.stockisto.com/api/public/v1/intake/batches \
-H "X-API-Key: <YOUR_INTAKE_KEY>" \
-H "Content-Type: application/json" \
--data '{"contractVersion":"1.0","source":"scraper","idempotencyKey":"<UNIQUE_BATCH_KEY>","records":[{"kind":"retailer-company","naturalKey":"<UNIQUE_RETAILER_KEY>","payload":{"name":"<RETAILER_NAME>"}}]}'
A new batch returns 202 with its id, status and a Location status link. Repeating the same idempotencyKey with the submitting key returns 200 and the existing batch with duplicate: true. It adds no volume, even when your daily quota is exhausted. The key is unique within the tenant; a collision with another credential returns 409.
| Field | Rule |
|---|---|
contractVersion | Required: 1.0. |
source | Required: the key's bound source. |
idempotencyKey | Required, at most 200 characters. |
description | Optional, at most 500 characters. |
metadata | Optional JSON object. |
records | From 1 to 50,000 records. |
kind | Required; supplier-company, retailer-company, installer-company and retailer-stock have appliers. Other valid kinds stay staged. |
naturalKey | Required for those four kinds; at most 512 characters. |
payload | Required JSON object; at most 256 KB. |
provenance | Optional source, fetchedAt (UTC, no future time), confidence (0 to 1) and sourceRef (at most 1024 characters). |
Read validationErrors for rejected records. Valid records continue; an invalid envelope or a batch with no valid records is refused.
3. Read status and review
GET /api/public/v1/intake/batches lists only batches submitted by this key. Use GET /api/public/v1/intake/batches/<BATCH_ID> for one batch. Another key's batch returns 404, including within the same tenant.
Statuses are received, validated, staged, in_review, applied, partially_applied and rejected. Source batches stop at in_review unless an operator has granted source trust for auto-apply. An unusually large removal always requires review. Check the status to confirm application; acceptance alone does not mean publication.
An operator can register an HTTPS callback URL on the key. Terminal states applied, partially_applied and rejected trigger a signed import.completed delivery.
4. Limits
| Limit | Value |
|---|---|
| Request body | 64 MB |
| Records per batch | 50,000 |
| Record payload | 256 KB |
| Requests per key | 30 per minute |
| Batches per UTC day | 200 by default; up to 10,000 at issuance |
| Records per UTC day | 500,000 by default; up to 10,000,000 at issuance |
A daily refusal returns 429, error: "intake_quota_exceeded" and a quota object with dailyBatchLimit, batchesToday, dailyRecordLimit, recordsToday and resetAt. Honour Retry-After; resume after the reset instead of repeatedly resubmitting.
5. Recover from a refusal
| Status | Next step |
|---|---|
| 400 | Correct the fields listed in errors. |
| 401 | Ask the operator to issue or rotate the key. |
| 403 | Match the bound source and use an api:intake key. |
| 404 | Read the batch with its submitting key. |
| 409 | Choose a new idempotencyKey; another credential owns it. |
| 413 | Split the batch into smaller requests. |
| 429 | Wait for Retry-After or the daily resetAt. |
For tenant imports, use the Public imports API instead.
For retailer file feeds, see Retailer feeds.