This page exists in one language only. Some pages here are English, some Swedish.
Public Imports API
Overview
The public imports API lets your integration push market data (companies, brands, products, retailer locations, offers) straight into Stockisto on a schedule you control, instead of preparing a file for the retailer import workbook. It is a different surface: this endpoint takes an NDJSON bundle over the API key surface; the workbook is a CSV/XLSX upload reviewed by hand in the dashboard.
Supplier keys only
Imports are a supplier surface. An API key belonging to a retailer or installer tenant gets a 403 here, because the market graph this endpoint feeds is built from supplier-submitted data.
Authentication
Send your API key as a bearer token, or in the X-API-Key header:
Authorization: Bearer sk_...
The key needs the api:write scope (write implies read). Create one on the Developers page in
Supplier Admin. The API surface needs the api.access entitlement, which the Growth plan and above
include; without it every call answers 402. Each call also draws one unit from your monthly API
request quota. Usage is shown on the Developers page.
Every field, scope and error shape is generated from the API code, so treat the public API reference as the source of truth alongside this guide.
The two operations
POST /api/public/v1/imports?mode=dry-run|apply
Submit an NDJSON bundle as the request body (Content-Type: application/x-ndjson). The endpoint
answers 202 Accepted with an importId and queues the bundle. Nothing is validated or applied
inline.
mode=dry-run(the default whenmodeis omitted): classifies every row and produces a report without writing anything.mode=apply: stages a reviewable changeset. A Stockisto operator reviews and applies it before any live row changes. Approved rows draw on your monthly import row quota at that step; dry runs and rejected changesets draw nothing.
Run a dry run first, read its report with the status endpoint, then resubmit the same bundle with
mode=apply once it looks right. Both modes report the same rejections, so the dry run catches
them before anything is staged.
GET /api/public/v1/imports/{importId}
Polls the batch you created. Only batches created through this endpoint are visible here; dashboard uploads are a separate, internal batch source. A batch belonging to another tenant, or an unknown id, answers 404, the same as one that never existed.
The NDJSON bundle shape
Each line is one JSON record with an entity property naming its contract table, for example
brands, companies, products, product_identifiers, offers, assortment_mappings or
suppressions. A single manifest
line may lead the stream; when present, its major version and counts are checked, and a mismatch
rejects the whole bundle. The record shapes, required fields and validation rules are defined once,
in MARKET-DATA-CONTRACT v1.0, section 9.1 (Bundle layout). This guide does not restate them.
Everything a bundle writes lands in your tenant's own namespace. A bundle can never touch another
tenant's records or the shared feed graph. A suppressions line names a record to forget with
target_entity and key; that is how a delisting or a right-to-be-forgotten request travels.
Per-row errors (broken_json, unsupported_country, dangling_fk and others) never fail the
batch; the row is reported and the rest continues.
Example request
dry-run request
curl -X POST "https://api.test.stockisto.com/api/public/v1/imports?mode=dry-run" \ -H "Authorization: Bearer sk_..." \ -H "Content-Type: application/x-ndjson" \ --data-binary @your-bundle.ndjson
Replace sk_... with your own key and your-bundle.ndjson with your bundle file. Never commit a
real key or real customer data to a script or a repository.
Reading the status
GET /api/public/v1/imports/{importId} returns the batch's current state:
| Field | Meaning |
|---|---|
status | pending, processing, completed, pending-review, rolledBack or failed |
mode | dry-run or apply, as submitted |
totalRows / validRows / errorRows | Row counts from validation |
report | The full validation report, once processing finishes |
quotaExceeded | true when an apply was refused for exceeding your import row quota, otherwise false |
quota | The limit, usage and reset for that quota; present only when quotaExceeded is true |
An apply batch reports pending-review from the moment it is staged until the operator applies
it, then completed. A dry run reports completed as soon as its report is ready.
Limits and quota
The request body is capped at 10 MB; a larger upload answers 413. Applying a changeset draws on
your per-tenant import row quota, which depends on your plan. A quota refusal on apply comes back
as a quotaExceeded batch, not as an HTTP error, and the changeset stays staged: applying again
after an upgrade proceeds.
When a batch is applied, subscribers to the import.completed webhook (Developers page) receive a
signed delivery carrying the importId and the row counts.
Failure outcomes
| Status | When |
|---|---|
| 202 Accepted | The bundle was queued for processing |
| 400 Bad Request | mode is neither dry-run nor apply, the body is empty, or the NDJSON cannot be read |
| 401 Unauthorized | The API key is missing or invalid |
| 402 Payment Required | Your plan does not include API access |
| 403 Forbidden | The key's tenant is not a supplier |
| 404 Not Found | No import with that id exists for your tenant |
| 413 Payload Too Large | The upload is over 10 MB |
| 429 Too Many Requests | The rate limit or your monthly API request quota is exhausted; honor Retry-After |
Looking for the dashboard-based workflow instead? See the retailer import workbook guide.