← All documentationREST API

Products, barcodes, orders, webhooks.

One API key, straightforward HTTP, no SDK to install. Built for shop-management systems, label printers, and warehouse tools that need to talk to Astra Atlas directly.

Getting an API key

In the Astra Atlas desktop app: Settings → Integrations → New Integration, source type Custom API. You'll get an API key (shown once — save it) and a webhook secret. Every request below authenticates with that key; nothing is ever derived from the request body, so a bad actor can't impersonate another account by guessing an ID.

Authentication

Send your API key as a header on every request:

x-api-key: YOUR_API_KEY

Missing or invalid key → 401. A paused integration → 403. A revoked one → 401, permanently. Rate limits (requests/minute) are set per integration and returned as X-RateLimit-* headers; exceeding them returns 429 with a reset_at timestamp.

Create a product

POST/webhooks/products

Leave barcode out and Astra Atlas generates a valid, unique EAN-13 and returns it in the response — the common case for a system that doesn't maintain its own barcode registry.

curl -X POST https://api.astrastudio.tech/webhooks/products \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sku": "SHIRT-RED-M",
    "name": "Red Cotton Shirt (M)",
    "selling_price": 599,
    "cost_price": 350,
    "gst_rate": 12
  }'

Response — 201 Created

{
  "success": true,
  "product": {
    "sku": "SHIRT-RED-M",
    "barcode": "2048371902614",
    "name": "Red Cotton Shirt (M)",
    "selling_price": 599,
    "cost_price": 350,
    "gst_rate": 12,
    "current_stock": 0,
    "is_active": true
  }
}

Fields:

skustring, requiredYour own identifier. Unique per account, not globally.
namestring, required
barcodestring, optionalOmit it and Astra Atlas generates a valid, unique EAN-13 for you — this is the recommended default.
categorystring, optional
unitstring, optionale.g. "pcs", "kg"
cost_pricenumber, optional
selling_pricenumber, optional
mrpnumber, optional
gst_ratenumber, optional0–100
hsn_codestring, optional

409 SKU_EXISTS if that SKU already exists on your account — SKUs are never silently overwritten by a create call.

Update a product (e.g. write a barcode onto it)

PATCH/webhooks/products/:sku

Look the product up by the SKU you gave it. Send only the fields you want to change — this is exactly how an external label-printing or inventory system writes a barcode back onto a product it didn't create through Astra Atlas in the first place.

curl -X PATCH https://api.astrastudio.tech/webhooks/products/SHIRT-RED-M \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "barcode": "2048371902614" }'

404 if the SKU doesn't exist on your account. 409 BARCODE_EXISTS if that exact barcode is already assigned to a different product — it is never silently reassigned.

Look up products

GET/webhooks/products

List active products with current stock. Supports category, limit, offset query params.

GET/webhooks/products/:sku

Fetch a single product by SKU. 404 if it doesn't exist or isn't active.

Ingest an order

POST/webhooks/orders

For a storefront or marketplace pushing sales into Astra Atlas as they happen.

curl -X POST https://api.astrastudio.tech/webhooks/orders \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "WEB-10234",
    "customer": { "name": "Priya Sharma", "phone": "9876543210" },
    "items": [
      { "sku": "SHIRT-RED-M", "quantity": 1, "unit_price": 599, "gst_rate": 12 }
    ]
  }'

order_id is your own reference — re-sending the same one is safe and returns the original result (200, status: "DUPLICATE") rather than creating a second sale.

Outbound webhooks

Configure a webhook URL for your integration (desktop app → Integrations → your integration's "Outbound webhook" field) and Astra Atlas POSTs to it when a product is created — useful if a second system also needs to know, without polling.

Payload — product.created

{
  "event": "product.created",
  "tenant_id": "a1b2c3d4-...",
  "data": { "sku": "SHIRT-RED-M", "barcode": "2048371902614", ... },
  "delivery_id": "e5f6...",
  "timestamp": "2026-10-02T04:30:00.000Z"
}

Every request carries an X-Astra-Signature header — HMAC-SHA256 of the raw request body, using the same webhook secret you were shown when the integration was created:

const crypto = require('crypto');

function isValid(rawBody, signatureHeader, webhookSecret) {
  const expected = crypto
    .createHmac('sha256', webhookSecret)
    .update(rawBody)
    .digest('hex');
  return expected === signatureHeader;
}

Verify against the raw body bytes, before any JSON parsing — re-serializing and comparing can change whitespace and silently break the signature check. A non-2xx response gets exactly one retry, 5 seconds later.

Error shape

Every error response is JSON with at least an error code and, usually, a human-readable message:

{ "success": false, "error": "SKU_EXISTS", "message": "Product with SKU 'SHIRT-RED-M' already exists" }

Need something this API doesn't cover yet?

Tell us what you're building — we add endpoints based on real integrations.

Contact Support