API Reference

The SpireStock REST API lets you programmatically manage orders, users, products, and workspace settings for your sales & distribution operations.

i

Base URL

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

Authentication

Two credentials are accepted. Send one or the other on every request — only login and signup are unauthenticated.

API key — the credential for servers, scheduled jobs and integrations. Create one under API Keys & Webhooks and send it as a header:

X-API-Key: df_9f3a1c7e2b8d...

JWT bearer token — for browser sessions, obtained from login or OTP verification:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Tokens expire after 15 days, and only one is valid per user at a time — signing in again invalidates the previous one. Logging in also requires a Cloudflare Turnstile token that only a browser can obtain, so anything server-side needs an API key. See Getting Started for scopes and the full comparison.

Requests without an API key must also send a descriptive User-Agent of at least 10 characters — defaults like curl/8.5.0, python-requests/2.31.0 and Node’s node are rejected with 403. Requests carrying X-API-Key are exempt.

Rate Limits

The API enforces rate limits per IP and per authenticated user:

  • General endpoints: 120 requests/min, 2,000 requests/hour
  • Login / OTP: 20 requests per 15 minutes (IP-based)
  • Signup: 5 requests per hour (IP-based)
  • Export endpoints: 5 requests/min, 50 requests/hour
  • Report endpoints: 20 requests/min, 200 requests/hour

When rate-limited you will receive a 429 Too Many Requests response with a Retry-After header.

Error Format

{
  "response_code": 400,
  "message": "Validation failed"
}

Pagination

List endpoints return paginated results. Use page and limit query parameters. The response includes a pagination object with total, total_pages, page, and limit.

Authentication

POST/auth/login

Authenticate with email and password. Returns a JWT token, user profile, navigation modules, and workspace details.

Request Body
NameTypeRequiredDescription
emailstringYesUser email address
passwordstringYesAccount password
curl -X POST https://api.spirestock.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "your-password"
  }'
POST/auth/otp/request

Request a one-time password sent via SMS for passwordless login.

Request Body
NameTypeRequiredDescription
phonestringYesPhone number to receive OTP
curl -X POST https://api.spirestock.com/api/v1/auth/otp/request \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+919876543210"
  }'
POST/auth/otp/verify

Verify the OTP and receive a JWT token. Completes passwordless authentication.

Request Body
NameTypeRequiredDescription
phonestringYesPhone number used in OTP request
otpstringYesThe OTP code received via SMS
curl -X POST https://api.spirestock.com/api/v1/auth/otp/verify \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+919876543210",
    "otp": "482910"
  }'
GET/auth/me

Retrieve the authenticated user’s profile, role, and organization context.

curl https://api.spirestock.com/api/v1/auth/me \
  -H "Authorization: Bearer YOUR_TOKEN"

Signup

POST/signup/register

Register a new organization and admin user. Creates the workspace, default settings, and returns a JWT token.

Request Body
NameTypeRequiredDescription
first_namestringYesFirst name of the admin user
last_namestringYesLast name of the admin user
official_emailstringYesAdmin email address
primary_contact_numberstringYesAdmin phone number
passwordstringYesPassword (min 8 characters)
organization_namestringYesName of the organization/business
curl -X POST https://api.spirestock.com/api/v1/signup/register \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Jane",
    "last_name": "Smith",
    "official_email": "[email protected]",
    "primary_contact_number": "+919876543210",
    "password": "secureP@ss123",
    "organization_name": "Acme Dairy"
  }'

Orders

GET/orders

List orders with pagination, filtering by status, date range, user, and search query. Status values are integers: 1 (initiated), 2 (forwarded), 3 (approved), 4 (delivered).

Parameters
NameTypeRequiredDescription
pagenumberNoPage number (default: 1)(default: 1)
limitnumberNoItems per page (default: 20, max: 100)(default: 20)
statusnumberNoFilter by status: 1 (initiated), 2 (forwarded), 3 (approved), 4 (delivered)
date_fromstringNoStart date (YYYY-MM-DD)
date_tostringNoEnd date (YYYY-MM-DD)
user_idnumberNoFilter orders by a specific user ID
searchstringNoSearch by order code or user name
curl "https://api.spirestock.com/api/v1/orders?page=1&limit=20&status=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/orders

Create a new order. Items are specified as an array of product variant IDs with quantities.

Request Body
NameTypeRequiredDescription
user_idnumberYesThe customer (retailer/distributor) user ID
itemsarrayYesArray of { product_variant_id, quantity }
order_datestringNoOrder date (YYYY-MM-DD)
delivery_datestringNoRequested delivery date (YYYY-MM-DD)
curl -X POST https://api.spirestock.com/api/v1/orders \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 42,
    "items": [
      { "product_variant_id": 10, "quantity": 20 },
      { "product_variant_id": 15, "quantity": 10 }
    ],
    "delivery_date": "2026-06-02"
  }'
GET/orders/{id}

Retrieve a single order by ID, including items, user details, and delivery info.

Parameters
NameTypeRequiredDescription
idnumberYesOrder ID (integer)
curl https://api.spirestock.com/api/v1/orders/142 \
  -H "Authorization: Bearer YOUR_TOKEN"
PATCH/orders/{id}/status

Update the status of an order. Status flow: 1 (initiated) → 2 (forwarded) → 3 (approved) → 4 (delivered).

Parameters
NameTypeRequiredDescription
idnumberYesOrder ID (integer)
Request Body
NameTypeRequiredDescription
order_statusnumberYesNew status: 2 (forwarded), 3 (approved), or 4 (delivered)
curl -X PATCH https://api.spirestock.com/api/v1/orders/142/status \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "order_status": 3
  }'

Users

GET/users

List all users in the organization with pagination and type filtering. User types: 0 (admin), 1 (employee), 2 (distributor).

Parameters
NameTypeRequiredDescription
pagenumberNoPage number (default: 1)
limitnumberNoItems per page (default: 20, max: 100)
typestringNoFilter by type: admin, employee, distributor
searchstringNoSearch by name, email, or phone
statusnumberNoFilter by status: 1 (active), 0 (inactive)
curl "https://api.spirestock.com/api/v1/users?type=distributor&page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/users

Create a new user in the organization. User type determines their role in the system.

Request Body
NameTypeRequiredDescription
first_namestringYesFirst name
last_namestringYesLast name
official_emailstringNoEmail address
primary_contact_numberstringYesPhone number
passwordstringYesInitial password
role_idnumberYesRole ID
user_typenumberYesUser type: 0 (admin), 1 (employee), 2 (distributor)
curl -X POST https://api.spirestock.com/api/v1/users \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Priya",
    "last_name": "Singh",
    "official_email": "[email protected]",
    "primary_contact_number": "+919123456789",
    "password": "secureP@ss123",
    "role_id": 3,
    "user_type": 2
  }'
GET/users/{id}

Retrieve a single user profile by ID, including role and organization details.

Parameters
NameTypeRequiredDescription
idnumberYesUser ID (integer)
curl https://api.spirestock.com/api/v1/users/42 \
  -H "Authorization: Bearer YOUR_TOKEN"

Products

GET/products

List all products in the catalog with optional search filter. Products include their class and variants.

Parameters
NameTypeRequiredDescription
pagenumberNoPage number (default: 1)
limitnumberNoItems per page (default: 20, max: 100)
searchstringNoSearch by product name
statusnumberNoFilter by status: 1 (active), 0 (inactive)
curl "https://api.spirestock.com/api/v1/products?search=milk&status=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/products

Add a new product to the catalog with optional variants.

Request Body
NameTypeRequiredDescription
product_namestringYesProduct name
product_class_idnumberYesProduct class/category ID
product_hsnstringNoHSN code for tax classification
product_descriptionstringNoProduct description
variantsarrayNoArray of { variant_name, item_sku_code, mrp, sp } variant objects
curl -X POST https://api.spirestock.com/api/v1/products \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "product_name": "Toned Milk",
    "product_class_id": 1,
    "product_hsn": "0401",
    "variants": [
      { "variant_name": "500ml", "item_sku_code": "TM-500", "mrp": 25.00, "sp": 22.00 },
      { "variant_name": "1L", "item_sku_code": "TM-1000", "mrp": 48.00, "sp": 42.00 }
    ]
  }'

Dashboard

GET/dashboard/stats

Retrieve summary statistics for the organization dashboard including order counts by status, employee metrics, revenue, and collection data.

curl https://api.spirestock.com/api/v1/dashboard/stats \
  -H "Authorization: Bearer YOUR_TOKEN"
GET/dashboard/monthly-sales

Retrieve product-wise sales data with daily trends, monthly totals, and year-over-year comparison. Returns data grouped by product class.

curl https://api.spirestock.com/api/v1/dashboard/monthly-sales \
  -H "Authorization: Bearer YOUR_TOKEN"

Exports

GET/exports/orders

Export orders as XLSX or PDF. Supports status and date range filters.

Parameters
NameTypeRequiredDescription
formatstringNoExport format: xlsx (default) or pdf(default: xlsx)
statusnumberNoFilter by order status (1-4)
date_fromstringNoStart date (YYYY-MM-DD)
date_tostringNoEnd date (YYYY-MM-DD)
production_unit_idnumberNoFilter by production unit
curl "https://api.spirestock.com/api/v1/exports/orders?format=xlsx&date_from=2026-05-01&date_to=2026-05-31" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -o orders-export.xlsx
GET/exports/users

Export user list as XLSX or PDF with optional type and status filters.

Parameters
NameTypeRequiredDescription
formatstringNoExport format: xlsx (default) or pdf(default: xlsx)
typestringNoFilter by user type: admin, employee, distributor
statusnumberNoFilter by status: 1 (active), 0 (inactive)
curl "https://api.spirestock.com/api/v1/exports/users?format=pdf&type=distributor" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -o users-export.pdf
GET/exports/sales

Export sales report as XLSX or PDF. Includes revenue breakdown by product class and trends.

Parameters
NameTypeRequiredDescription
formatstringNoExport format: xlsx (default) or pdf(default: xlsx)
date_fromstringNoStart date (YYYY-MM-DD)
date_tostringNoEnd date (YYYY-MM-DD)
curl "https://api.spirestock.com/api/v1/exports/sales?format=xlsx&date_from=2026-01-01&date_to=2026-05-31" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -o sales-report.xlsx

Workspace

GET/workspace/config

Retrieve the current workspace configuration including branding, organizational details, and operational settings.

curl https://api.spirestock.com/api/v1/workspace/config \
  -H "Authorization: Bearer YOUR_TOKEN"
PUT/workspace/config

Update workspace configuration. Only admin users can modify workspace settings.

Request Body
NameTypeRequiredDescription
logostringNoLogo URL
primary_colorstringNoBrand primary color hex code
secondary_colorstringNoBrand secondary color hex code
org_footer_namestringNoOrganization footer/legal name
org_addressstringNoOrganization address
contact_numberstringNoContact phone number
curl -X PUT https://api.spirestock.com/api/v1/workspace/config \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "primary_color": "#2563eb",
    "org_footer_name": "Acme Dairy Co. Pvt. Ltd.",
    "contact_number": "+911234567890"
  }'

API Keys & Webhooks

GET/developer/api-keys

List the API keys issued for your workspace. The secret itself is never returned — only the prefix, so you can identify a key you already saved. Workspace administrators only.

curl https://api.spirestock.com/api/v1/developer/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/developer/api-keys

Issue a new API key. The plaintext key is returned once, in this response only — it is stored as a SHA-256 hash and cannot be retrieved again. Send it as X-API-Key on subsequent requests. Workspace administrators only; requires a session token, not an API key.

Request Body
NameTypeRequiredDescription
namestringYesLabel to identify the key later
scopesstringNoComma-separated. Actions: read (GET/HEAD), write (all methods, implies read). Optional resource scopes confine the key to those route groups, e.g. 'read,orders'. Use '*' for full access.(default: read)
expires_in_daysintegerNo1-3650. Omit for a key that never expires
curl -X POST https://api.spirestock.com/api/v1/developer/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Warehouse sync",
    "scopes": "read,orders",
    "expires_in_days": 90
  }'
DELETE/developer/api-keys/{id}

Revoke an API key. The record is kept for audit purposes and its status is set to 0. Workspace administrators only.

Parameters
NameTypeRequiredDescription
idintegerYesAPI key ID
curl -X DELETE https://api.spirestock.com/api/v1/developer/api-keys/3 \
  -H "Authorization: Bearer YOUR_TOKEN"
GET/developer/webhooks

List the webhook endpoints registered for your workspace, including delivery health via last_triggered_at and failure_count. Signing secrets are never included — rotate if you lost one. The response also carries supported_events.

curl https://api.spirestock.com/api/v1/developer/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/developer/webhooks

Register a webhook endpoint. A signing secret is generated and returned in this response only — store it and use it to verify deliveries. The URL must be HTTPS and resolve to a public address; private, loopback and link-local targets are rejected. Workspace administrators only.

Request Body
NameTypeRequiredDescription
namestringYesLabel to identify the endpoint
urlstringYesHTTPS URL that will receive the POST. Must resolve to a public address
eventsstring[] | stringNoAny of order.created, order.delivered, user.created — as an array or comma-separated string. Unknown events are rejected(default: order.created,order.delivered)
curl -X POST https://api.spirestock.com/api/v1/developer/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Order events",
    "url": "https://example.com/hooks/spirestock",
    "events": ["order.created", "order.delivered"]
  }'
PUT/developer/webhooks/{id}

Update a webhook endpoint. Omitted fields are left unchanged. Send status 0 to pause deliveries without deleting the endpoint or rotating its secret — pausing also cancels deliveries already queued for it. Workspace administrators only.

Parameters
NameTypeRequiredDescription
idintegerYesWebhook ID
Request Body
NameTypeRequiredDescription
namestringNoLabel to identify the endpoint
urlstringNoHTTPS URL that will receive the POST
eventsstring[] | stringNoEvents to subscribe to, as an array or comma-separated string
statusintegerNo1 to deliver, 0 to pause
curl -X PUT https://api.spirestock.com/api/v1/developer/webhooks/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["order.created", "order.delivered", "user.created"],
    "status": 1
  }'
DELETE/developer/webhooks/{id}

Delete a webhook endpoint permanently. Deliveries stop immediately, any queued deliveries are cancelled, and the signing secret is discarded. Workspace administrators only.

Parameters
NameTypeRequiredDescription
idintegerYesWebhook ID
curl -X DELETE https://api.spirestock.com/api/v1/developer/webhooks/1 \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/developer/webhooks/{id}/rotate-secret

Issue a new signing secret for an endpoint. The only way to recover a secret lost after creation, and the correct response to one that leaked. Deliveries are signed with the new secret immediately, with no grace period — deploy it to your endpoint first. Workspace administrators only.

Parameters
NameTypeRequiredDescription
idintegerYesWebhook ID
curl -X POST https://api.spirestock.com/api/v1/developer/webhooks/1/rotate-secret \
  -H "Authorization: Bearer YOUR_TOKEN"
POST/developer/webhooks/{id}/test

Send a webhook.test payload, signed exactly like a real event, so you can confirm your endpoint is reachable and your signature check works before real events fire. Never retried. A delivery failure is reported in the body rather than as an error status — you asked whether the endpoint is reachable, and the answer 'no' is still a successful answer.

Parameters
NameTypeRequiredDescription
idintegerYesWebhook ID
curl -X POST https://api.spirestock.com/api/v1/developer/webhooks/1/test \
  -H "Authorization: Bearer YOUR_TOKEN"
GET/developer/webhook-deliveries

Recent delivery attempts, newest first — what was sent, what your endpoint returned, and what is still queued for retry. The first place to look when an endpoint is not receiving what you expect.

Parameters
NameTypeRequiredDescription
webhook_idintegerNoLimit to a single endpoint
statusstringNoOne of pending, sending, sent, dead
limitintegerNo1-200(default: 50)
curl "https://api.spirestock.com/api/v1/developer/webhook-deliveries?webhook_id=1&status=dead" \
  -H "Authorization: Bearer YOUR_TOKEN"