---
title: "API Reference"
description: "Every SpireStock REST endpoint with request parameters, cURL examples, and sample responses."
source: https://0.0.0.0:8006/api-reference
---

# 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](#developer) and send it as a header:

```
X-API-Key: df_9f3a1c7e2b8d...
```

**JWT bearer token** — for browser sessions, obtained from [login](#auth) or [OTP verification](#auth):

```
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](/docs/getting-started#authentication) 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

| 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": "user@example.com",
    "password": "your-password"
  }'

POST `/auth/otp/request`

Request 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"
  }'

POST `/auth/otp/verify`

Verify 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"
  }'

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

| 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": "jane@acmedairy.com",
    "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

| 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"

POST `/orders`

Create 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"
  }'

GET `/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"

PATCH `/orders/{id}/status`

Update 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

GET `/users`

List 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"

POST `/users`

Create 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": "priya@example.com",
    "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

| 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

GET `/products`

List 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"

POST `/products`

Add 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

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

| 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

GET `/exports/users`

Export 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

GET `/exports/sales`

Export 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

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

| 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

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

| 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
  }'

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

| 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"

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

| 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"\]
  }'

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

| 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
  }'

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

| 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"

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

| 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"

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

| 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"

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

| 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"
