API Reference
The SpireStock REST API lets you programmatically manage orders, users, products, and workspace settings for your sales & distribution operations.
Base URL
https://api.spirestock.com/api/v1Authentication
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
/auth/loginAuthenticate with email and password. Returns a JWT token, user profile, navigation modules, and workspace details.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User email address |
password | string | Yes | Account password |
curl -X POST https://api.spirestock.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "your-password"
}'/auth/otp/requestRequest a one-time password sent via SMS for passwordless login.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Phone number to receive OTP |
curl -X POST https://api.spirestock.com/api/v1/auth/otp/request \
-H "Content-Type: application/json" \
-d '{
"phone": "+919876543210"
}'/auth/otp/verifyVerify the OTP and receive a JWT token. Completes passwordless authentication.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Phone number used in OTP request |
otp | string | Yes | The 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"
}'/auth/meRetrieve the authenticated user’s profile, role, and organization context.
curl https://api.spirestock.com/api/v1/auth/me \ -H "Authorization: Bearer YOUR_TOKEN"
Signup
/signup/registerRegister a new organization and admin user. Creates the workspace, default settings, and returns a JWT token.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | First name of the admin user |
last_name | string | Yes | Last name of the admin user |
official_email | string | Yes | Admin email address |
primary_contact_number | string | Yes | Admin phone number |
password | string | Yes | Password (min 8 characters) |
organization_name | string | Yes | Name 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
/ordersList 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
| Name | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (default: 1)(default: 1) |
limit | number | No | Items per page (default: 20, max: 100)(default: 20) |
status | number | No | Filter by status: 1 (initiated), 2 (forwarded), 3 (approved), 4 (delivered) |
date_from | string | No | Start date (YYYY-MM-DD) |
date_to | string | No | End date (YYYY-MM-DD) |
user_id | number | No | Filter orders by a specific user ID |
search | string | No | Search 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"
/ordersCreate a new order. Items are specified as an array of product variant IDs with quantities.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
user_id | number | Yes | The customer (retailer/distributor) user ID |
items | array | Yes | Array of { product_variant_id, quantity } |
order_date | string | No | Order date (YYYY-MM-DD) |
delivery_date | string | No | Requested 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"
}'/orders/{id}Retrieve a single order by ID, including items, user details, and delivery info.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | number | Yes | Order ID (integer) |
curl https://api.spirestock.com/api/v1/orders/142 \ -H "Authorization: Bearer YOUR_TOKEN"
/orders/{id}/statusUpdate the status of an order. Status flow: 1 (initiated) → 2 (forwarded) → 3 (approved) → 4 (delivered).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | number | Yes | Order ID (integer) |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
order_status | number | Yes | New 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
/usersList all users in the organization with pagination and type filtering. User types: 0 (admin), 1 (employee), 2 (distributor).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (default: 1) |
limit | number | No | Items per page (default: 20, max: 100) |
type | string | No | Filter by type: admin, employee, distributor |
search | string | No | Search by name, email, or phone |
status | number | No | Filter by status: 1 (active), 0 (inactive) |
curl "https://api.spirestock.com/api/v1/users?type=distributor&page=1" \ -H "Authorization: Bearer YOUR_TOKEN"
/usersCreate a new user in the organization. User type determines their role in the system.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | First name |
last_name | string | Yes | Last name |
official_email | string | No | Email address |
primary_contact_number | string | Yes | Phone number |
password | string | Yes | Initial password |
role_id | number | Yes | Role ID |
user_type | number | Yes | User 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
}'/users/{id}Retrieve a single user profile by ID, including role and organization details.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | number | Yes | User ID (integer) |
curl https://api.spirestock.com/api/v1/users/42 \ -H "Authorization: Bearer YOUR_TOKEN"
Products
/productsList all products in the catalog with optional search filter. Products include their class and variants.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (default: 1) |
limit | number | No | Items per page (default: 20, max: 100) |
search | string | No | Search by product name |
status | number | No | Filter by status: 1 (active), 0 (inactive) |
curl "https://api.spirestock.com/api/v1/products?search=milk&status=1" \ -H "Authorization: Bearer YOUR_TOKEN"
/productsAdd a new product to the catalog with optional variants.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
product_name | string | Yes | Product name |
product_class_id | number | Yes | Product class/category ID |
product_hsn | string | No | HSN code for tax classification |
product_description | string | No | Product description |
variants | array | No | Array 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
/dashboard/statsRetrieve 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"
/dashboard/monthly-salesRetrieve 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
/exports/ordersExport orders as XLSX or PDF. Supports status and date range filters.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
format | string | No | Export format: xlsx (default) or pdf(default: xlsx) |
status | number | No | Filter by order status (1-4) |
date_from | string | No | Start date (YYYY-MM-DD) |
date_to | string | No | End date (YYYY-MM-DD) |
production_unit_id | number | No | Filter 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
/exports/usersExport user list as XLSX or PDF with optional type and status filters.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
format | string | No | Export format: xlsx (default) or pdf(default: xlsx) |
type | string | No | Filter by user type: admin, employee, distributor |
status | number | No | Filter 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
/exports/salesExport sales report as XLSX or PDF. Includes revenue breakdown by product class and trends.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
format | string | No | Export format: xlsx (default) or pdf(default: xlsx) |
date_from | string | No | Start date (YYYY-MM-DD) |
date_to | string | No | End 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
/workspace/configRetrieve 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"
/workspace/configUpdate workspace configuration. Only admin users can modify workspace settings.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
logo | string | No | Logo URL |
primary_color | string | No | Brand primary color hex code |
secondary_color | string | No | Brand secondary color hex code |
org_footer_name | string | No | Organization footer/legal name |
org_address | string | No | Organization address |
contact_number | string | No | Contact 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
/developer/api-keysList 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"
/developer/api-keysIssue 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
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Label to identify the key later |
scopes | string | No | Comma-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_days | integer | No | 1-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
}'/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
| Name | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | API key ID |
curl -X DELETE https://api.spirestock.com/api/v1/developer/api-keys/3 \ -H "Authorization: Bearer YOUR_TOKEN"
/developer/webhooksList 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"
/developer/webhooksRegister 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
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Label to identify the endpoint |
url | string | Yes | HTTPS URL that will receive the POST. Must resolve to a public address |
events | string[] | string | No | Any 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"]
}'/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
| Name | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Webhook ID |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
name | string | No | Label to identify the endpoint |
url | string | No | HTTPS URL that will receive the POST |
events | string[] | string | No | Events to subscribe to, as an array or comma-separated string |
status | integer | No | 1 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
}'/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
| Name | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Webhook ID |
curl -X DELETE https://api.spirestock.com/api/v1/developer/webhooks/1 \ -H "Authorization: Bearer YOUR_TOKEN"
/developer/webhooks/{id}/rotate-secretIssue 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
| Name | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Webhook ID |
curl -X POST https://api.spirestock.com/api/v1/developer/webhooks/1/rotate-secret \ -H "Authorization: Bearer YOUR_TOKEN"
/developer/webhooks/{id}/testSend 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
| Name | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Webhook ID |
curl -X POST https://api.spirestock.com/api/v1/developer/webhooks/1/test \ -H "Authorization: Bearer YOUR_TOKEN"
/developer/webhook-deliveriesRecent 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
| Name | Type | Required | Description |
|---|---|---|---|
webhook_id | integer | No | Limit to a single endpoint |
status | string | No | One of pending, sending, sent, dead |
limit | integer | No | 1-200(default: 50) |
curl "https://api.spirestock.com/api/v1/developer/webhook-deliveries?webhook_id=1&status=dead" \ -H "Authorization: Bearer YOUR_TOKEN"