Getting Started

Everything you need to authenticate, make your first API call, and start building with the SpireStock REST API.

Prerequisites

  • An active SpireStock workspace with admin or developer access.
  • An API key, created from the dashboard under Developer → API Keys. Creating one requires workspace administrator access.
  • A tool for making HTTP requests — cURL, Postman, or any HTTP client library.
💡

Don't have a workspace yet?

Sign up at app.spirestock.com/signup to create a free workspace and start building immediately.

Base URL

All API endpoints are served from a single base URL. Every path referenced in this documentation is relative to:

https://api.spirestock.com/api/v1

For example, the full URL for listing orders would be https://api.spirestock.com/api/v1/orders.

Authentication

SpireStock accepts two credentials. Which one you want depends on whether a browser is involved.

CredentialUse it forLifetime
API key — X-API-KeyServers, scheduled jobs, ERP connectors, anything without a browserUntil you revoke it (or its optional expiry)
JWT — Authorization: BearerBrowser sessions signed in through the dashboard15 days, and only one active per user
⚠️

Server-side? Use an API key.

/auth/login requires a Cloudflare Turnstile token, which only a browser can obtain — a server calling it gets 400 Security verification required. On top of that, a user holds only one valid JWT at a time, so signing into the dashboard invalidates the token your integration was using. API keys have neither problem.

Authenticating with an API key

Create a key in the dashboard under Developer → API Keys, or with the API itself while signed in as an administrator:

Create a key
curl -X POST https://api.spirestock.com/api/v1/developer/api-keys \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Warehouse sync",
    "scopes": "read,orders",
    "expires_in_days": 90
  }'
Response (201 Created)
{
  "response_code": 201,
  "message": "API key created. Save this key — it won't be shown again.",
  "data": {
    "id": 3,
    "key": "df_9f3a1c7e2b8d4a6f0c5e1b7a3d9f2e4c6a8b0d2f4e6a8c0b2d4f6a8c0e2b4d6f",
    "name": "Warehouse sync",
    "key_prefix": "df_9f3a1c",
    "scopes": "read,orders",
    "expires_at": "2026-11-16T00:00:00.000Z"
  }
}
🚨

The key is shown exactly once

Only a SHA-256 hash of the key is stored, so it cannot be retrieved later — not by you, not by support. Save it to your secret store the moment you create it. Lost a key? Revoke it and issue a new one.

Send it on every request as a header:

X-API-Key: df_9f3a1c7e2b8d...

Scopes

A key’s scopes string mixes two kinds of token: actions (read, write) and optional resources (orders, users, products, …). read permits GET and HEAD; write permits every method and implies read. Name no resource and the key reaches every endpoint it is allowed to; name one or more and it is confined to those.

ScopesWhat the key can do
readRead any endpoint
read,ordersRead /orders and nothing else
write,ordersFull access to /orders, read and write
read,writeFull access to every allowed endpoint
*The same as read,write
💡

Endpoints an API key cannot reach

Regardless of scope, keys are refused on /auth, /signup, /developer, /billing, /platform, /super-admin, /portal, /driver-app and /support. That is why key and webhook management needs a signed-in administrator — a leaked key cannot mint more keys, repoint your webhooks, or start a purchase.

Authenticating with a session token

If you are building something a person signs into, exchange their credentials for a JWT. The request must carry a turnstile_token from the Turnstile widget on your page:

Request
curl -X POST https://api.spirestock.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "User-Agent: AcmeIntegration/1.0" \
  -d '{
    "email": "YOUR_EMAIL",
    "password": "YOUR_PASSWORD",
    "turnstile_token": "TOKEN_FROM_THE_TURNSTILE_WIDGET"
  }'
Response (200 OK)
{
  "response_code": 200,
  "message": "Login successful",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 1,
    "first_name": "Jane",
    "last_name": "Developer",
    "official_email": "[email protected]",
    "role_name": "Admin",
    "user_type": 0,
    "organization_id": 5,
    "organization_name": "Acme Dairy"
  },
  "workspace": {
    "workspace_id": "ws_x9y8z7",
    "slug": "acme-dairy",
    "display_name": "Acme Dairy",
    "plan": "professional",
    "status": 1
  }
}

Include the token in the Authorization header using the Bearer scheme:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
⚠️

Token expiry & single active session

Tokens expire after 15 days. Only one is valid per user at a time — logging in again, logging out, or changing the password invalidates the previous one. When you receive 401 Unauthorized, re-authenticate.

🚨

Token storage best practices

Never store JWT tokens in localStorage or sessionStorage — they are accessible to any JavaScript running on the page (XSS-vulnerable). Instead:

  • Server-side apps: Store tokens in memory or encrypted server-side sessions.
  • Browser apps: Use httpOnly cookies set by your backend proxy, or keep tokens in memory only (they will be lost on page refresh, which is the safer trade-off).
  • Never include tokens in URLs, log files, or error reporting payloads.

Set a User-Agent

The API rejects requests whose User-Agent is missing, shorter than 10 characters, or matches a known scraping tool. Several HTTP clients trip this by default:

ClientSends by defaultResult
cURLcurl/8.5.0403
Python requestspython-requests/2.31.0403
Node fetchnode (4 characters)403
✅

Two ways to satisfy this

Send X-API-Key — keyed requests skip the check entirely, because the key already identifies you. Or set a descriptive User-Agent naming your integration, which is good practice either way:

Identifying your client
curl https://api.spirestock.com/api/v1/orders \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "User-Agent: AcmeIntegration/1.0"

Your First Request

With a key in hand, fetch a list of orders from your workspace. Keep the key in an environment variable — never in source control.

GET /orders
curl https://api.spirestock.com/api/v1/orders \
  -H "X-API-Key: $SPIRESTOCK_API_KEY"

Every request is scoped to the organization the key belongs to. There is no tenant parameter to pass and no way to reach another workspace’s data.

What You Can Build

A single API key reaches most of the workspace — orders, outlets, products, routes, reports and more. A read key pulls data out; a write key pushes data back in. Below are the common integrations, and the endpoint groups each one uses.

Build thisWhat it doesEndpoint groups
ERP / accounting syncKeep SAP, Zoho, Oracle or Tally in step with SpireStock — masters and orders flowing both ways./masters, /orders, /products, /imports, /exports
Order automationCreate orders from an external system, or read order and delivery status into yours./orders, /secondary-sales
Master-data managementBulk-manage outlets, SKUs, price lists, routes and the other 40+ master entities from your own tooling./masters, /imports
Reporting & BI pipelinesFeed sales, stock and activity data into a warehouse, dashboard or scheduled export./reports, /dashboard, /exports
Logistics & trackingSync vehicle, crate and live-location data with a fleet or WMS system./logistics, /tracking, /crates
Event-driven automationReact the moment something happens — an order is placed or delivered — instead of polling.Webhooks

For the full, always-current list of every endpoint and its schema, see the API Reference. A key can reach every group except the ones that manage credentials, billing or the platform itself — see Scopes above.

Building with AI instead of code

If the goal is to ask questions of the workspace rather than build a pipeline, connect an AI assistant over MCP instead of writing against the REST API directly. It wraps a read key and lets Claude, Cursor or any MCP-compatible client answer questions in plain language:

  • “How many orders were delivered last week, by outlet?”
  • “Which distributors haven’t ordered this month?”
  • “Summarise today’s sales for the north region.”

The MCP connection is read-only — it can look at orders, accounts, products and reports, but never place an order, change a record or alter billing. See Connect AI Tools for setup.

💡

Which one do I want?

API key — a builder’s credential. Automate, sync and integrate; read to pull, write to push.
MCP — an analyst’s credential. Let an AI read the workspace and answer questions. Read-only.

Rate Limits

To ensure fair usage across all tenants, the API enforces rate limits on a per-IP or per-token basis. When a limit is exceeded the API responds with 429 Too Many Requests.

Endpoint GroupLimitWindow
POST /signup/register5 requestsPer hour
POST /auth/login20 requestsPer 15 minutes
General endpoints120 requestsPer minute
General endpoints2,000 requestsPer hour
Export endpoints5 requestsPer minute
Report endpoints20 requestsPer minute
💡

Rate-limit headers

Every response includes X-RateLimit-Limit and X-RateLimit-Remaining so you can throttle before you are throttled. A 429 also carries Retry-After in seconds.

✅

Each key gets its own budget

An API key is metered separately from the administrator who created it, and separately from every other key. A busy integration cannot rate-limit a colleague out of the dashboard, and splitting work across two keys gives you two budgets.

Error Handling

The API uses standard HTTP status codes. Errors include a JSON body with a response_code matching the HTTP status and a human-readable message field.

Error response example
{
  "response_code": 400,
  "message": "Validation failed"
}
Status CodeMeaningCommon Cause
400Bad RequestInvalid or missing request body fields
401UnauthorizedMissing, revoked, or expired credential
403ForbiddenMissing scope, an endpoint API keys cannot reach, a suspended workspace, or a rejected User-Agent
404Not FoundResource does not exist or belongs to another workspace
429Too Many RequestsRate limit exceeded — back off and retry
500Internal Server ErrorUnexpected server-side failure — contact support if it persists

Next Steps

Now that you can authenticate and make requests, explore further:

  • API Reference — Full endpoint documentation with request/response schemas.
  • Webhooks — Receive real-time event notifications for orders, users, and payments.
  • SDKs — Official client libraries for Node.js, Python, and cURL examples.
  • Connect AI Tools — Let Claude, Cursor, or any MCP client read your workspace in plain language. Published on npm today.