The StockAI API

Almost everything you do inside StockAI can also be done through the API: upload sales, train and read the forecast, read the traffic light, record orders, manage suppliers and warehouses. Connect it to your ERP, your POS or any system of your own.

Base URL
https://app.stockai.es/api/v1
Authentication
Authorization: Bearer sk_live_…
Endpoints
298 documented173 read125 write
GET/api/v1/planning
Request
curl "$STOCKAI/planning" \
  -H "Authorization: Bearer $STOCKAI_KEY"
Response
200 OK application/json
{
  "success": true,
  "data": {},
  "meta": {
    "timestamp": "2026-10-02T08:00:00Z"
  }
}

Authentication

Every call carries an API key in the Authorization header. Keys are created in the app, under Automation → API Keys, and shown once: StockAI stores only a hash.

shell
export STOCKAI=https://app.stockai.es/api/v1
export STOCKAI_KEY=sk_live_…

curl "$STOCKAI/planning" \
  -H "Authorization: Bearer $STOCKAI_KEY"

A key acts as itself, not as the person who created it: it keeps working if that person leaves the company.

Read keys and write keys

When you create a key you choose what it may do. Every endpoint in the reference says which kind of key it needs.

ReadReads everything a viewer sees: traffic light, forecasts, suppliers, orders, reports.
Read and writeAlso creates and changes, like an analyst: uploads files, trains, records orders, edits inventory and suppliers.

A read key that tries to write gets 403 with error_code api_key_scope_insufficient, and nothing changes.

What a key can never do

Some actions belong to people, not systems. With an API key they answer 403 api_key_route_not_exposed:

  • Sign in, refresh tokens or recover passwords.
  • Create, invite or change users and their permissions.
  • Create, list or revoke API keys: a key cannot mint another.
  • Configure the installation or the account's channels.
  • Export or delete the account.
  • What belongs to one person: their inbox, their assistant conversations, their preferences.
  • What only an administrator can do (for example, change the currency or the active period).

Sending an order or an alert by email or WhatsApp with a write key requires the account to have at least one administrator with a verified email (otherwise: 403 api_key_tenant_unverified).

Limits

Authentication
/ min120 calls per minute per key.
APIThe API, the MCP server and the WhatsApp bot come with the Pro, Max and Corporate plans; the Free plan does not include them.

Over the limit you get 429 with a Retry-After header (seconds). The same 429 serves the per-minute limit and the daily cap, and its body has no error_code.

There are no X-RateLimit-* headers: the only signal is the 429 with Retry-After. Count your own calls or wait for the 429.

Metering and purchase

The API comes with the Pro (2,000 calls a day per key), Max (20,000) and Corporate (no daily cap) plans. We count every API-key call that reached an endpoint, by day (UTC) and by key; refused calls (invalid key, no permission or over the limit) do not count. An administrator sees the month's usage in the app, on the API screen.

Errors

Almost every error carries a stable error_code and, where it applies, error_params with the values: branch on the code, not on the detail text, which is an English hint and may change. The framework's own answers (missing header, unknown route, wrong method) and the 429 carry only detail.

api_key_invalid401 the key does not exist, was revoked or has expired.
api_key_route_not_exposed403 that endpoint cannot be called with an API key.
api_key_scope_insufficient403 the key is read-only and the endpoint writes.
api_key_tenant_unverified403 sending anything outside StockAI needs a verified administrator.
validation_error422 the body or parameters are invalid; detail is a list with one object per field.
PLAN_LIMIT_REACHED403 a usage ceiling was reached; detail is an object and error_params says which.
server_busy503 the server is saturated; retry after Retry-After.
(no error_code)401 the Authorization header is missing or is not “Bearer sk_live_…”: detail is “Not authenticated”.
(no error_code)429 per-minute limit or daily cap: wait Retry-After seconds.
(no error_code)404 / 405 unknown route or method not allowed.

The shape of detail

stringMost errors: one English sentence.
list422 validation_error: [{ type, loc, msg, input }], one per invalid field; loc says where (for example ["body", "name"]).
objectPLAN_LIMIT_REACHED: { code, limit, current, max, tier }, the same content as error_params.
403 Example: a read key that writes
{
  "detail": "This endpoint writes and the API key is read-only. Use a write key.",
  "error_code": "api_key_scope_insufficient",
  "error_params": { "required_scope": "write", "key_scope": "read" }
}

Response format

Every JSON response is wrapped: { "success": true, "data": …, "meta": { "timestamp": … } }. Your payload is in data, which is an object or a list depending on the endpoint; paginated lists carry their list in data.items.

200 application/json
{
  "success": true,
  "data": {},
  "meta": {
    "timestamp": "2026-10-02T08:00:00Z"
  }
}

Endpoints that return a file (Excel, PDF, CSV) answer with the file itself, with no wrapper.

The MCP endpoint (POST /mcp) speaks JSON-RPC 2.0 and does not use this wrapper.

Types and formats

DatesDates are YYYY-MM-DD; instants are ISO 8601 in UTC, for example 2026-10-01T08:00:00+00:00.
NumbersQuantities and amounts are JSON numbers, not strings. Amounts are in the account's currency (GET /tenant/currency).
Empty valuesA field with no value usually arrives as null instead of being omitted.
IdentifiersOpaque prefixed strings (sess_…, ds_…, sup_…): store them as they are.
SignalsThe traffic light uses PEDIR_YA, PEDIR_PRONTO, OK and SOBRESTOCK: fixed values that are not translated.

Pagination

There are three forms, and each endpoint declares its own in its parameters:

skip and limitSessions, session summaries, data sources and datasets. The response has items, total, skip and limit.
limit and offsetAlert activity (/alerts/activity). The response has items, total, limit and offset.
limit onlyNewest first, up to limit: alerts, order history, setup gaps, shrinkage and retraining history.
no paginationThe rest return the whole set and are narrowed with their filters, for example signal or supplier on /inventory/status.

Idempotency

POST /inventory/log-po and POST /inventory/po accept the Idempotency-Key header: one unique value (a UUID) per order you mean to place. Repeating the request with the same key returns the order that was already created (200 with replayed: true) instead of a second one; the same key with different lines answers 409 po_idempotency_key_reused. Every other write endpoint is not idempotent: before retrying a write whose result you did not see, check whether it was applied.

HTTP
Idempotency-Key: 3f1c9a5e-7d62-4b0e-9d6a-2c8f4a1b5e70

For AI clients (MCP)

The same key opens an MCP server at POST /mcp with five read-only tools, so an AI assistant can query your traffic light. By design it writes nothing. GET /mcp answers 405: the server does not open a stream to the client.

Endpoint reference

Generated from the service itself: if an endpoint is listed here, it can be called with an API key. Example responses are real calls to a test account.

POST Explain a SKU's recommendation
AI narratives

Explain a SKU's recommendation

POST/api/v1/ai/narrative/forecast-explanation
Read keyReturns 200 · application/json

Explains a specific SKU's inventory signal and recommendation in plain language.

Request

Headers
  • AuthorizationBearer sk_live_…required

    Your API key. Always required.

  • Content-Typeapplication/jsonrequired
Body

application/jsonThe body is required.

object An object.
  • skustringrequired
  • session_idstringrequired
  • profilestringoptionaldefault "distributor"
  • languagestringoptionaldefault "es"

Responses

200 On success

No example response was captured for this endpoint. Every JSON answer comes in this envelope; what data holds depends on the endpoint.

Possible errors

Besides the errors of each endpoint, any call made with a key can answer:

  • 401Authorization header missing, or API key invalid, revoked or expired.
  • 403Key may not call this endpoint, is read-only on a write, or a permission check refused it.
  • 429Per-minute limit or daily ceiling reached; honour Retry-After.
  • 422Validation Error
Errors
Request
curl -X POST "$STOCKAI/ai/narrative/forecast-explanation" \
  -H "Authorization: Bearer $STOCKAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sku":"SKU-001","session_id":"<session_id>","profile":"distributor","language":"es"}'
Response
200 OK application/json
{
  "success": true,
  "data": {},
  "meta": {
    "timestamp": "2026-10-02T08:00:00Z"
  }
}

Put your own AI to work forecasting your sales. Today.

Three ways to start, depending on how much you want to commit right now. All three lead to the same product.

Create your account

With the whole engine. Upload your sales file and see your first forecast, and with it your first list of what to order.

Create my account

Look before giving your email

An instant trial account with sample data. It lasts 24 hours and is then erased.

Try it without signing up

Talk to us

For the corporate plan, the source code, or to see it with your data and someone beside you. We answer within 24 hours.

Sales and contact: contacto@stockai.es. Phone: +506 7186 2820.

Sales forecasting made in Costa Rica, for companies across Latin America.