Crossmart for developers
Crossmart keeps one catalog and one stock ledger, and publishes them to every store a seller connects (Shopify, eBay, Google Merchant and more). Everything the dashboard does goes through a public REST API, so your scripts, integrations and AI agents can do it too.
The API
Section titled “The API”| Base URL | https://api.crossmart.io/api/v1 (self-hosted: http://localhost:3000/api/v1) |
| API reference | On this site, generated from the OpenAPI spec |
| Interactive docs | api.crossmart.io/api/docs |
| OpenAPI spec | api.crossmart.io/api/docs-json |
| Format | JSON in and out. Money is a decimal string ("19.90"), times are ISO 8601 in UTC |
The API reference lists every endpoint with its fields. The interactive docs let you try them with your key (Authorize → api_key). Generate a client in any language from the OpenAPI spec, or use the TypeScript or Python SDK.
Versioning
Section titled “Versioning”The version is in the path: /api/v1. Within a version, changes are additive only: new
endpoints, new optional fields, new response fields and new enum values. Write clients that
ignore fields they don’t know and tolerate new enum values. Removing or renaming anything goes
through a deprecation period and, if it can’t be avoided, a new version.
Workspaces and organizations
Section titled “Workspaces and organizations”An organization is the account that holds the plan and billing. It has one or more workspaces: a workspace is one business, with its own catalog, stock, stores, orders and members. Almost every endpoint is scoped to a workspace:
/api/v1/workspaces/{workspaceId}/products/api/v1/workspaces/{workspaceId}/ordersA workspace you can’t access answers 404, the same as one that doesn’t exist, so ids don’t leak.
Plan limits (active listings, connected stores, API keys…) count across the organization’s
workspaces.
Authentication
Section titled “Authentication”API keys
Section titled “API keys”An API key belongs to one workspace and has a role. Create one in the dashboard under
Settings → API keys (or with POST /api/v1/workspaces/{workspaceId}/api-keys). The full key
is shown once; Crossmart stores only a hash. Send it in the x-api-key header:
curl https://api.crossmart.io/api/v1/api-key -H "x-api-key: $CROSSMART_API_KEY"GET /api/v1/api-key answers with the key’s workspaceId, role and permissions, so a program
holding only the key can find its workspace.
| Role | Typical use |
|---|---|
VIEWER |
Read-only reporting and dashboards |
EDITOR |
Catalog and stock sync, publishing to stores, generating AI content for review |
APPROVER |
Reviewing AI suggestions |
ADMIN |
Store pricing and sync rules, members and keys |
CUSTOM |
A role the workspace defined, with exactly the permissions you pick |
A key can’t be an Owner and never has more access than the person who created it. Each endpoint
requires one permission; a key without it gets 403 Requires the <permission> permission. The
permissions of each role are in Roles and permissions. Give each
integration its own key with the smallest role that works, so you can revoke it alone.
OAuth for AI agents (coming soon)
Section titled “OAuth for AI agents (coming soon)”AI agents such as Claude and ChatGPT will be able to connect through OAuth instead of a pasted
key: the seller signs in, picks a workspace and approves the access. The agent then sends an
access token as Authorization: Bearer <token>, limited to the scopes the seller approved and to
their own role. The SDKs already accept an access token.
Sessions
Section titled “Sessions”The dashboard signs people in with a session cookie (Better Auth, under /api/auth). Use API keys
for programs; session endpoints such as /api/v1/me are meant for the web app.
Errors
Section titled “Errors”Errors use the HTTP status and a JSON body:
{ "statusCode": 404, "error": "Not Found", "message": "Product not found" }| Status | Meaning |
|---|---|
| 400 | Invalid input. message is a list with one entry per problem (see below). |
| 401 | The key or token is missing, wrong, revoked or expired. |
| 402 | The plan doesn’t allow it. The body adds a machine-readable code, the feature, plan, limit and usage. |
| 403 | The role lacks the permission. |
| 404 | Not found, or not in this workspace. |
| 409 | Conflicts with existing data, such as a duplicate SKU or handle. |
| 429 | Too many requests (see rate limits). |
| 5xx | A server problem. Safe requests (GET, PUT, DELETE) can be retried with backoff. |
A 400 lists every problem:
{ "statusCode": 400, "error": "Bad Request", "message": ["title should not be empty", "variants must contain at least 1 elements"]}A 402 has code set to plan_limit_reached or plan_feature_not_included, plus the feature,
the plan, its limit and current usage, so you can tell the user what to upgrade.
Pagination
Section titled “Pagination”List endpoints return one page at a time:
{ "items": [ … ], "nextCursor": "6f1c…", "total": 137 }limit: page size, 1 to 100 (the default is 25 on most lists).cursor: pass the previous page’snextCursorto read the next page.nextCursorisnullon the last page.page: a 1-based page number, for tables that jump between pages. It wins overcursor.total: how many items match the filters in all.
Unlike page numbers, cursors do not skip or repeat items when rows are added while you read. The
SDKs walk the pages for you: listAll() in TypeScript, iter() in Python.
Rate limits
Section titled “Rate limits”Most /api/v1 endpoints have no rate limit today. Two are limited, per workspace and per caller
(a person or an API key), because each call spends AI credits:
| Endpoint | Limit |
|---|---|
POST /api/v1/workspaces/{workspaceId}/ai/content-generations |
10 requests a minute |
POST /api/v1/workspaces/{workspaceId}/ai/content-drafts |
30 requests a minute |
Sign-in and sign-up under /api/auth are limited too. Past a limit the API answers
429 Too Many Requests with a Retry-After header. Limits per key may be added to other
endpoints later, answered the same way. Handle 429 now (the SDKs do), and batch your work: list
with large pages, and use the bulk endpoints such as
POST …/channel-connections/{connectionId}/products/add.
Asynchronous work
Section titled “Asynchronous work”Talking to marketplaces takes time and can fail, so changes that reach a store run in the
background. The API records the change and answers at once; a worker then publishes it. Publishing
a product creates a listing with status PENDING, which becomes ACTIVE when the store accepts it
or ERROR (with the store’s message in lastError) when it refuses. The
quickstart shows how to follow it.
Where to go next
Section titled “Where to go next”- Quickstart
- TypeScript SDK and Python SDK
- MCP server for AI agents
- Roles and permissions
- API reference
- Architecture, for contributors