Download OpenAPI specification:Download
The Laabam One API lets your systems and approved third parties read and write data in your company's Laabam One account — invoices, customers, products, payments — and send messages over SMS, WhatsApp and email.
Every request authenticates with two headers — X-Client-Id and
X-Client-Secret, created in Settings → API Keys. See the
Authentication and Security guides
for the full details. Each operation below is marked x-status: available
(callable today) or x-status: planned (contract defined, not yet built).
✅ Read, create, send & void available (create posts the Sales JE + moves stock; INR). Update (PATCH draft) planned.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| limit | integer [ 1 .. 100 ] Default: 25 Page size (1–100). |
| cursor | string Opaque cursor from the previous response's paging.next_cursor. |
| status | string Enum: "unpaid" "partial" "paid" Filters on the invoice's payment_status (not the |
| customer_id | string |
{- "data": [
- {
- "id": "inv_5c1a",
- "number": "INV/2025-26/041",
- "status": "unpaid",
- "customer_id": "string",
- "currency": "INR",
- "subtotal": "3000.00",
- "tax_amount": "540.00",
- "round_off": "0.00",
- "total": "3540.00",
- "due_amount": "3540.00",
- "invoice_date": "2019-08-24",
- "due_date": "2019-08-24",
- "items": [
- {
- "product_id": "string",
- "quantity": 0,
- "unit_price": "1500.00",
- "tax_rate": 18,
- "amount": "3540.00"
}
], - "created_at": "2019-08-24T14:15:22Z"
}
], - "paging": {
- "next_cursor": "string",
- "has_more": true
}
}Creates an invoice, posts the Sales journal entry (DR receivable, CR sales + GST split) and deducts stock — the exact same accounting engine as the in-app flow. Totals, tax and round-off are computed server-side and are authoritative (client-sent totals are ignored). Each line requires item_name, quantity, unit, unit_price and tax_rate. INR only in v1 (recurring, attachments and pay-at-create are app-only).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| Idempotency-Key | string <uuid> A unique UUID so retries don't double‑create/charge/send. Cached 24h. |
| customer_id required | string |
| invoice_date required | string <date> |
| due_date | string <date> |
required | Array of objects (InvoiceItemCreate) non-empty |
| document_type | string Default: "invoice" Enum: "invoice" "quotation" "estimate" "proforma_invoice" "sales_order" |
| invoice_number | string <= 50 characters Auto-generated when omitted. |
| reference_number | string <= 255 characters |
| gst_invoice_type | string Enum: "regular" "bill_of_supply" "export_sez" |
| reverse_charge | string Enum: "Y" "N" |
| terms | string |
| notes | string |
{- "customer_id": "string",
- "invoice_date": "2019-08-24",
- "due_date": "2019-08-24",
- "items": [
- {
- "item_name": "string",
- "quantity": 0.01,
- "unit": "pcs",
- "unit_price": 1500,
- "tax_rate": 18,
- "product_id": 0,
- "description": "string",
- "hsn_code": "string",
- "discount_percent": 100
}
], - "document_type": "invoice",
- "invoice_number": "string",
- "reference_number": "string",
- "gst_invoice_type": "regular",
- "reverse_charge": "Y",
- "terms": "string",
- "notes": "string"
}{- "data": {
- "id": "inv_5c1a",
- "number": "INV/2025-26/041",
- "status": "unpaid",
- "customer_id": "string",
- "currency": "INR",
- "subtotal": "3000.00",
- "tax_amount": "540.00",
- "round_off": "0.00",
- "total": "3540.00",
- "due_amount": "3540.00",
- "invoice_date": "2019-08-24",
- "due_date": "2019-08-24",
- "items": [
- {
- "product_id": "string",
- "quantity": 0,
- "unit_price": "1500.00",
- "tax_rate": 18,
- "amount": "3540.00"
}
], - "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "data": {
- "id": "inv_5c1a",
- "number": "INV/2025-26/041",
- "status": "unpaid",
- "customer_id": "string",
- "currency": "INR",
- "subtotal": "3000.00",
- "tax_amount": "540.00",
- "round_off": "0.00",
- "total": "3540.00",
- "due_amount": "3540.00",
- "invoice_date": "2019-08-24",
- "due_date": "2019-08-24",
- "items": [
- {
- "product_id": "string",
- "quantity": 0,
- "unit_price": "1500.00",
- "tax_rate": 18,
- "amount": "3540.00"
}
], - "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
| customer_id required | string |
| invoice_date required | string <date> |
| due_date | string <date> |
required | Array of objects (InvoiceItemCreate) non-empty |
| document_type | string Default: "invoice" Enum: "invoice" "quotation" "estimate" "proforma_invoice" "sales_order" |
| invoice_number | string <= 50 characters Auto-generated when omitted. |
| reference_number | string <= 255 characters |
| gst_invoice_type | string Enum: "regular" "bill_of_supply" "export_sez" |
| reverse_charge | string Enum: "Y" "N" |
| terms | string |
| notes | string |
{- "customer_id": "string",
- "invoice_date": "2019-08-24",
- "due_date": "2019-08-24",
- "items": [
- {
- "item_name": "string",
- "quantity": 0.01,
- "unit": "pcs",
- "unit_price": 1500,
- "tax_rate": 18,
- "product_id": 0,
- "description": "string",
- "hsn_code": "string",
- "discount_percent": 100
}
], - "document_type": "invoice",
- "invoice_number": "string",
- "reference_number": "string",
- "gst_invoice_type": "regular",
- "reverse_charge": "Y",
- "terms": "string",
- "notes": "string"
}{- "data": {
- "id": "inv_5c1a",
- "number": "INV/2025-26/041",
- "status": "unpaid",
- "customer_id": "string",
- "currency": "INR",
- "subtotal": "3000.00",
- "tax_amount": "540.00",
- "round_off": "0.00",
- "total": "3540.00",
- "due_amount": "3540.00",
- "invoice_date": "2019-08-24",
- "due_date": "2019-08-24",
- "items": [
- {
- "product_id": "string",
- "quantity": 0,
- "unit_price": "1500.00",
- "tax_rate": 18,
- "amount": "3540.00"
}
], - "created_at": "2019-08-24T14:15:22Z"
}
}Voids (soft-deletes) the invoice and reverses all its side-effects — its journal entries, any payments + their JEs, and restores deducted stock — the same reversal as the app. Returns a summary of what was reversed.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "data": {
- "id": "string",
- "voided": true,
- "reversal": { }
}
}Renders the invoice PDF (using your configured print template) and queues it for email to the customer — the same render the in‑app "Send" button uses. Recipients default to the invoice customer's email; override with email or emails[] (max 10). A draft invoice is marked as sent. Only channel: email is available today; WhatsApp invoice delivery is planned.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
| channel | string Default: "email" Value: "email" |
string <email> Single recipient (overrides the customer email). | |
| emails | Array of strings <email> [ items <email > ] Multiple recipients (max 10). |
| message | string <= 1000 characters Optional note included in the email. |
{- "channel": "email",
- "email": "user@example.com",
- "emails": [
- "user@example.com"
], - "message": "string"
}{- "data": {
- "id": "string",
- "channel": "email",
- "status": "queued",
- "invoice_id": "string",
- "to": [
- "string"
], - "queued_count": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}✅ Read, create, update & delete available (create also opens the Sundry Debtors ledger account).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| limit | integer [ 1 .. 100 ] Default: 25 Page size (1–100). |
| cursor | string Opaque cursor from the previous response's paging.next_cursor. |
| q | string Free‑text search (name / email / phone). |
{- "data": [
- {
- "id": "42",
- "customer_number": "string",
- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "gstin": "string",
- "pan": "string",
- "address": {
- "line1": "string",
- "city": "string",
- "state": "string",
- "postal_code": "string",
- "country": "IN"
}, - "currency": "string",
- "is_active": true,
- "created_at": "2019-08-24T14:15:22Z"
}
], - "paging": {
- "next_cursor": "string",
- "has_more": true
}
}Creates a customer and its Sundry Debtors ledger account (same path as the UI). name, state and pincode are required. opening_balance and profile images are NOT settable via the API (the opening-balance ledger entry remains a UI-only action).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| Idempotency-Key | string <uuid> A unique UUID so retries don't double‑create/charge/send. Cached 24h. |
| name required | string <= 255 characters |
string <email> <= 255 characters | |
| phone | string <= 20 characters |
| phone_country_code | string |
| alternate_phone | string <= 20 characters |
| address | string |
| address_label | string |
| area | string |
| city | string |
| state required | string |
| pincode required | string |
| country | string <= 2 characters ISO alpha-2. |
| gst_number | string <= 15 characters |
| gst_type | string |
| legal_name | string |
| pan_number | string <= 10 characters |
| customer_type | string Enum: "individual" "business" |
| currency_code | string = 3 characters |
| discount | number [ 0 .. 100 ] |
| credit_limit | number >= 0 |
| website_url | string <uri> |
| also_vendor | boolean |
| is_active | boolean |
| notes | string |
{- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "phone_country_code": "string",
- "alternate_phone": "string",
- "address": "string",
- "address_label": "string",
- "area": "string",
- "city": "string",
- "state": "string",
- "pincode": "string",
- "country": "st",
- "gst_number": "string",
- "gst_type": "string",
- "legal_name": "string",
- "pan_number": "string",
- "customer_type": "individual",
- "currency_code": "str",
- "discount": 100,
- "credit_limit": 0,
- "also_vendor": true,
- "is_active": true,
- "notes": "string"
}{- "data": {
- "id": "42",
- "customer_number": "string",
- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "gst_number": "string",
- "state": "string",
- "pincode": "string",
- "currency_code": "string",
- "is_active": true,
- "also_vendor": true,
- "account_id": 0,
- "vendor_account_id": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "data": {
- "id": "42",
- "customer_number": "string",
- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "gstin": "string",
- "pan": "string",
- "address": {
- "line1": "string",
- "city": "string",
- "state": "string",
- "postal_code": "string",
- "country": "IN"
}, - "currency": "string",
- "is_active": true,
- "created_at": "2019-08-24T14:15:22Z"
}
}Partial update — send only the fields you want to change. Renaming keeps the linked ledger account names in sync.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
| name required | string <= 255 characters |
string <email> <= 255 characters | |
| phone | string <= 20 characters |
| phone_country_code | string |
| alternate_phone | string <= 20 characters |
| address | string |
| address_label | string |
| area | string |
| city | string |
| state required | string |
| pincode required | string |
| country | string <= 2 characters ISO alpha-2. |
| gst_number | string <= 15 characters |
| gst_type | string |
| legal_name | string |
| pan_number | string <= 10 characters |
| customer_type | string Enum: "individual" "business" |
| currency_code | string = 3 characters |
| discount | number [ 0 .. 100 ] |
| credit_limit | number >= 0 |
| website_url | string <uri> |
| also_vendor | boolean |
| is_active | boolean |
| notes | string |
{- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "phone_country_code": "string",
- "alternate_phone": "string",
- "address": "string",
- "address_label": "string",
- "area": "string",
- "city": "string",
- "state": "string",
- "pincode": "string",
- "country": "st",
- "gst_number": "string",
- "gst_type": "string",
- "legal_name": "string",
- "pan_number": "string",
- "customer_type": "individual",
- "currency_code": "str",
- "discount": 100,
- "credit_limit": 0,
- "also_vendor": true,
- "is_active": true,
- "notes": "string"
}{- "data": {
- "id": "42",
- "customer_number": "string",
- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "gst_number": "string",
- "state": "string",
- "pincode": "string",
- "currency_code": "string",
- "is_active": true,
- "also_vendor": true,
- "account_id": 0,
- "vendor_account_id": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}Soft-deletes the customer and removes its debtor account. Blocked with 409 if the customer has invoices, payments or posted ledger transactions. If the record is also a vendor, only the customer role is removed (vendor data is retained).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "data": {
- "id": "string",
- "deleted": true
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| limit | integer [ 1 .. 100 ] Default: 25 Page size (1–100). |
| cursor | string Opaque cursor from the previous response's paging.next_cursor. |
| q | string |
| category_id | string |
{- "data": [
- {
- "id": "42",
- "name": "string",
- "sku": "string",
- "hsn_code": "string",
- "sale_price": 0,
- "mrp": 0,
- "gst_rate": 0,
- "track_inventory": true,
- "current_stock": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
], - "paging": {
- "next_cursor": "string",
- "has_more": true
}
}Creates a product. If track_stock is true and opening_stock > 0, an opening stock movement (and a batch when is_batch_tracked) is recorded. name and unit_id are required. Images, variants and bundles are not settable via the API.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| name required | string |
| unit_id required | integer Required. Must exist in the company's units. |
| type | string Default: "product" Enum: "product" "service" |
| invoice_name | string Defaults to |
| sku | string <= 100 characters Must be unique. |
| barcode | string <= 100 characters Must be unique. |
| category_id | integer |
| brand_id | integer |
| description | string |
| purchase_price | number >= 0 |
| selling_price | number >= 0 |
| mrp_price | number >= 0 |
| selling_price_tax_mode | string Enum: "exclusive" "inclusive" |
| gst_rate | number [ 0 .. 100 ] |
| hsn_code | string <= 20 characters |
| sac_code | string <= 20 characters |
| status | string Default: "active" Enum: "active" "inactive" |
| track_stock | boolean Create only — not updatable via PATCH. |
| opening_stock | number |
| min_stock | number |
| max_stock | number |
| low_stock_alert | boolean |
| is_batch_tracked | boolean |
| is_expiry_tracked | boolean |
{- "name": "string",
- "unit_id": 0,
- "type": "product",
- "invoice_name": "string",
- "sku": "string",
- "barcode": "string",
- "category_id": 0,
- "brand_id": 0,
- "description": "string",
- "purchase_price": 0,
- "selling_price": 0,
- "mrp_price": 0,
- "selling_price_tax_mode": "exclusive",
- "gst_rate": 18,
- "hsn_code": "string",
- "sac_code": "string",
- "status": "active",
- "track_stock": true,
- "opening_stock": 0,
- "min_stock": 0,
- "max_stock": 0,
- "low_stock_alert": true,
- "is_batch_tracked": true,
- "is_expiry_tracked": true
}{- "data": {
- "id": "42",
- "name": "string",
- "invoice_name": "string",
- "sku": "string",
- "unit_id": 0,
- "purchase_price": 0,
- "selling_price": 0,
- "mrp_price": 0,
- "gst_rate": 0,
- "track_stock": true,
- "status": "string",
- "current_stock": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "data": {
- "id": "42",
- "name": "string",
- "sku": "string",
- "hsn_code": "string",
- "sale_price": 0,
- "mrp": 0,
- "gst_rate": 0,
- "track_inventory": true,
- "current_stock": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}Partial update of scalar fields (name, prices, tax/HSN, sku, status, …). Stock and track_stock are NOT updatable here — use the stock-adjustments endpoint to move stock.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
| name | string |
| unit_id | integer |
| invoice_name | string |
| sku | string <= 100 characters |
| barcode | string <= 100 characters |
| category_id | integer |
| brand_id | integer |
| description | string |
| purchase_price | number >= 0 |
| selling_price | number >= 0 |
| mrp_price | number >= 0 |
| selling_price_tax_mode | string Enum: "exclusive" "inclusive" |
| gst_rate | number [ 0 .. 100 ] |
| hsn_code | string <= 20 characters |
| sac_code | string <= 20 characters |
| status | string Enum: "active" "inactive" |
| min_stock | number |
| max_stock | number |
| low_stock_alert | boolean |
{- "name": "string",
- "unit_id": 0,
- "invoice_name": "string",
- "sku": "string",
- "barcode": "string",
- "category_id": 0,
- "brand_id": 0,
- "description": "string",
- "purchase_price": 0,
- "selling_price": 0,
- "mrp_price": 0,
- "selling_price_tax_mode": "exclusive",
- "gst_rate": 100,
- "hsn_code": "string",
- "sac_code": "string",
- "status": "active",
- "min_stock": 0,
- "max_stock": 0,
- "low_stock_alert": true
}{- "data": {
- "id": "42",
- "name": "string",
- "invoice_name": "string",
- "sku": "string",
- "unit_id": 0,
- "purchase_price": 0,
- "selling_price": 0,
- "mrp_price": 0,
- "gst_rate": 0,
- "track_stock": true,
- "status": "string",
- "current_stock": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}Records a manual stock-adjustment movement and moves the product's current stock.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
| adjustment_type required | string Enum: "increase" "decrease" |
| quantity required | number >= 0.01 Always positive; direction is set by adjustment_type. |
| reason | string <= 100 characters |
| notes | string <= 500 characters |
{- "adjustment_type": "increase",
- "quantity": 0.01,
- "reason": "string",
- "notes": "string"
}{- "data": {
- "id": "string",
- "movement_id": "string",
- "adjustment_type": "string",
- "quantity": 0,
- "current_stock": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| limit | integer [ 1 .. 100 ] Default: 25 Page size (1–100). |
| cursor | string Opaque cursor from the previous response's paging.next_cursor. |
| invoice_id | string |
| customer_id | string |
{- "data": [
- {
- "id": "42",
- "payment_number": "string",
- "invoice_id": "string",
- "customer_id": "string",
- "amount": 3540,
- "currency": "string",
- "reference": "string",
- "status": "string",
- "payment_date": "2019-08-24",
- "created_at": "2019-08-24T14:15:22Z"
}
], - "paging": {
- "next_cursor": "string",
- "has_more": true
}
}Records a payment and posts the receipt journal entry (DR bank/cash, CR the customer's receivable) as the in-app "Record Payment" does, then updates the invoice's paid/due/status. payment_mode_id chooses the bank/cash account — list options via GET /payments/{company}/methods.
Currency: only invoices whose currency is INR or unset are accepted; any other value returns 422. This is a hard INR check, not your company's base currency — a non-INR-base tenant cannot record payments against its own foreign-currency invoices via this endpoint.
The journal entry is best-effort: if the cash/bank account, the receivable account or the financial year can't be resolved, the payment is still recorded and journal_entry_id comes back null.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| Idempotency-Key | string <uuid> A unique UUID so retries don't double‑create/charge/send. Cached 24h. |
| invoice_id required | string |
| amount required | number >= 0.01
|
| payment_date required | string <date> |
| payment_mode_id required | integer From GET /payments/{company}/methods. |
| tds_amount | number >= 0 TDS withheld by the buyer. Counts toward settling the invoice alongside |
| tds_section | string <= 40 characters |
| reference_number | string <= 100 characters |
| notes | string <= 500 characters |
{- "invoice_id": "string",
- "amount": 0.01,
- "payment_date": "2019-08-24",
- "payment_mode_id": 0,
- "tds_amount": 0,
- "tds_section": "string",
- "reference_number": "string",
- "notes": "string"
}{- "data": {
- "id": "42",
- "payment_number": "string",
- "invoice_id": "string",
- "amount": 0,
- "payment_date": "2019-08-24",
- "status": "string",
- "journal_entry_id": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "invoice": {
- "id": "string",
- "paid_amount": 0,
- "due_amount": 0,
- "status": "string",
- "payment_status": "string"
}
}
}Active payment modes for the company — use the returned id as payment_mode_id when recording a payment.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
{- "data": [
- {
- "id": "string",
- "name": "string",
- "mode_type": "string"
}
]
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "data": {
- "id": "42",
- "payment_number": "string",
- "invoice_id": "string",
- "customer_id": "string",
- "amount": 3540,
- "currency": "string",
- "reference": "string",
- "status": "string",
- "payment_date": "2019-08-24",
- "created_at": "2019-08-24T14:15:22Z"
}
}Reverses the payment — voids its journal entry and recomputes the invoice's paid/due/status. Full reversal only (partial refunds are not supported yet; no request body is read).
⚠️ The payment record is removed, not flagged. After a refund GET /payments/{company}/{id} returns 404, and refunding the same id twice also returns 404 — there is no refunded: true state to read back.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string Opaque resource identifier. |
| Idempotency-Key | string <uuid> A unique UUID so retries don't double‑create/charge/send. Cached 24h. |
{- "data": {
- "id": "string",
- "refunded": true
}
}✅ SMS, WhatsApp & Email available. Security‑sensitive — dedicated send scopes, lower rate limits and a daily cap. Path carries the company slug. Everything you need to configure a send — slug, endpoint, pe_id, and each approved sender_id with its template_ids and exact message text — is in Settings → API Keys → “Integration details”, with copy buttons. For India, read the DLT notes on Send an SMS first: a mismatched template is dropped by the carrier while this API still returns 202.
Sends an SMS via the company's gateway. Requires the messages:sms:send scope. Subject to the messaging rate limit + daily cap.
India (DLT) — read this before you debug for an afternoon. Pass an approved sender_id plus its registered template_id (and pe_id), and make message match the approved template text exactly — including punctuation and any sender suffix (e.g. ... -ACMEID). Variables occupy the {#var#} slots. sender_id and template_id must be a matched pair: the template is registered against one sender.
⚠️ A mismatch fails silently. If message does not match the registered template, or template_id is missing/wrong, the carrier DROPS the message — but this endpoint still returns 202. It will look like it worked while nothing is ever delivered. 202 means accepted, not delivered (lifecycle: queued → submitted → delivered); confirm real delivery with GET /messaging/{company}/messages/{id}.
Where to get all four values. Open Settings → API Keys → “Integration details”. It lists, with copy buttons: the company slug, the full endpoint URL, your pe_id, and every approved sender ID with its own templates nested underneath — each showing the template_id, the exact registered message text, the variable count and the character limit. Only approved rows appear, because anything else is dropped by the carrier.
Because the templates are grouped under their sender there, you can read off a valid sender_id + template_id pair directly instead of correlating two separate lists and guessing. A sender with no templates listed cannot send anything yet. The same data lives in Marketing → SMS Gateway (DLT Registration / Sender IDs / Templates) if you prefer to manage it there.
Copy the message text from that panel and substitute only the {#var#} slots — retyping it is how the trailing sender suffix gets lost.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| to required | string Recipient number, digits only (8–15). |
| message required | string <= 1000 characters |
| sender_id | string <= 11 characters An APPROVED sender ID, copied from Settings → API Keys → Integration details. Must be the sender the |
| template_id | string <= 64 characters Registered DLT template id, copied from under its sender in Settings → API Keys → Integration details. Omit it, or pair it with a different sender, and Indian carriers drop the SMS silently while this API still returns 202. |
| pe_id | string <= 64 characters DLT principal entity (PE) id, shown in Settings → API Keys → Integration details. One per company — the same value for every sender and template. |
| type | string Default: "transactional" Enum: "transactional" "promotional" |
{- "to": "919800000000",
- "message": "Your OTP is 123456",
- "sender_id": "ACMEID",
- "template_id": "1007487766981813506",
- "pe_id": "1001609937061127455",
- "type": "transactional"
}{- "data": {
- "id": "msg_7b3c",
- "channel": "sms",
- "status": "queued",
- "to": "string",
- "sent_at": "2019-08-24T14:15:22Z",
- "delivered_at": "2019-08-24T14:15:22Z",
- "read_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "error": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
}Sends via the company's Meta Cloud API provider. Business‑initiated messages must use a Meta‑APPROVED template; free text is only delivered inside an open 24‑hour customer‑service window. Requires the messages:whatsapp:send scope.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| to required | string |
| type | string Default: "template" Enum: "template" "text" |
object Required when type=template. | |
object Required when type=text. |
{- "to": "919800000000",
- "type": "template",
- "template": {
- "name": "invoice_due",
- "language": "en",
- "variables": [
- "Acme",
- "3540.00"
]
}, - "text": {
- "body": "Thanks for your order!"
}
}{- "data": {
- "id": "msg_7b3c",
- "channel": "sms",
- "status": "queued",
- "to": "string",
- "sent_at": "2019-08-24T14:15:22Z",
- "delivered_at": "2019-08-24T14:15:22Z",
- "read_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "error": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| id required | string The provider message id returned by a send call. |
{- "data": {
- "id": "msg_7b3c",
- "channel": "sms",
- "status": "queued",
- "to": "string",
- "sent_at": "2019-08-24T14:15:22Z",
- "delivered_at": "2019-08-24T14:15:22Z",
- "read_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "error": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
}Sends a transactional email through your company's configured email provider (Settings → Marketing → Email provider); if none is set the platform default mailer is used. The sender identity is taken from that provider — you cannot set an arbitrary from. HTML is sanitised server‑side (script/iframe/event‑handler vectors are stripped). Up to 50 recipients per call.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
required | Array of objects One recipient or an array. Each item may be a plain email string or an object. |
| subject required | string <= 255 characters |
| html required | string Email body as HTML. Sanitised server‑side before send. |
{- "to": [
- {
- "email": "user@example.com",
- "name": "string"
}
], - "subject": "string",
- "html": "string"
}{- "data": {
- "id": "msg_7b3c",
- "channel": "sms",
- "status": "queued",
- "to": "string",
- "sent_at": "2019-08-24T14:15:22Z",
- "delivered_at": "2019-08-24T14:15:22Z",
- "read_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "error": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
{- "data": [
- {
- "id": "string",
- "slug": "string",
- "title": "string",
- "department": "string",
- "location": "string",
- "employment_type": "string",
- "description": "string"
}
]
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| slug required | string |
{- "data": {
- "id": "string",
- "slug": "string",
- "title": "string",
- "department": "string",
- "location": "string",
- "employment_type": "string",
- "description": "string"
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| slug required | string |
| first_name required | string <= 100 characters |
| last_name | string <= 100 characters |
| email required | string <email> <= 255 characters |
| phone | string <= 30 characters |
| resume required | string <binary> Required. Allowed: pdf, doc, docx. Max 10 MB. |
| cover_letter | string <= 5000 characters |
| total_experience | number [ 0 .. 50 ] Years. |
| expected_salary | number |
| notice_period_days | integer >= 0 |
| linkedin_url | string <uri> <= 500 characters |
| skills | string A JSON-encoded string (not an array), e.g. '["PHP","Vue"]'. |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}Captures a lead. Send application/json, or multipart/form-data if you need to include an attachment file. Re-submitting an existing lead is de-duplicated server-side and still returns 200.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| first_name required | string |
| last_name required | string |
| email required | string <email> |
| phone | string |
| company_name | string |
| lead_type | string Enum: "contact" "rfp" "enquiry" "demo_request" |
| service | string |
| source | string |
| source_url | string <uri> |
| form_code | string |
| message | string <= 10000 characters |
| job_title | string |
| company_size | string |
| industry | string |
| country | string |
| services_needed | string |
| budget_range | string |
| timeline | string |
| project_overview | string |
| goals_expectations | string |
| current_systems | string |
| how_heard | string |
{- "first_name": "string",
- "last_name": "string",
- "email": "user@example.com",
- "phone": "string",
- "company_name": "string",
- "lead_type": "contact",
- "service": "string",
- "source": "string",
- "form_code": "string",
- "message": "string",
- "job_title": "string",
- "company_size": "string",
- "industry": "string",
- "country": "string",
- "services_needed": "string",
- "budget_range": "string",
- "timeline": "string",
- "project_overview": "string",
- "goals_expectations": "string",
- "current_systems": "string",
- "how_heard": "string"
}{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| productId required | string |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}Creates a sales order (document_type=sales_order, status draft) and starts a payment intent — it does not create an invoice, post a journal entry, or reserve or decrement stock. The order becomes a real invoice only after the payment gateway webhook confirms payment. A tenant customer is created (or matched by email, then by the last 9 digits of the phone) as a side effect.
Prices are server-authoritative when product_id is supplied: your unit_price and name are discarded and replaced with the catalogue values. They are only honoured for ad-hoc lines that omit product_id.
⚠️ This endpoint does not support idempotency — the Idempotency-Key header is ignored here, so a retry creates a duplicate order.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
required | Array of objects [ 1 .. 50 ] items |
required | object |
| currency required | string = 3 characters Enum: "INR" "USD" "EUR" "GBP" "AUD" "CAD" "SGD" "MYR" |
| source_website required | string <= 255 characters |
| return_url required | string <uri> <= 500 characters |
| cancel_url required | string <uri> <= 500 characters |
| tax_amount | number |
| shipping_amount | number |
| notes | string |
| metadata | object |
{- "items": [
- {
- "name": "string",
- "quantity": 0.001,
- "unit_price": 0.01,
- "product_id": 0,
- "description": "string",
- "hsn_sac_code": "string"
}
], - "customer": {
- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "address": "string",
- "city": "string",
- "state": "string",
- "pincode": "string",
- "country": "strin"
}, - "currency": "INR",
- "source_website": "string",
- "tax_amount": 0,
- "shipping_amount": 0,
- "notes": "string",
- "metadata": { }
}{- "success": true,
- "order_id": 0,
- "order_number": "string",
- "total_amount": 0,
- "currency": "string",
- "gateway": "razorpay",
- "payment_data": { }
}Returns an order created through this storefront checkout. Documents raised inside the app are not visible here and return 404, even though they live in the same company — this endpoint is deliberately scoped to storefront-origin orders only.
invoice_url stays null until the order converts to an invoice (i.e. until the payment webhook confirms payment).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| orderId required | string |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}✅ Available. Driving-school booking flow — service locations, instructors by suburb, lessons & packages, availability, and bookings with online payment. Accepts a secret key OR a browser publishable (pk_) key.
Active service locations (test centres / pickup points / offices).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
{- "success": true,
- "locations": [
- {
- "id": 0,
- "name": "string",
- "type": "test_center",
- "city": "string",
- "state": "string",
- "postcode": "string",
- "latitude": 0,
- "longitude": 0
}
]
}Bookable instructors, optionally filtered to those who service a suburb/postcode/point.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| lat | number Latitude (with lng) — distance match vs each instructor's radius_km. |
| lng | number Longitude (with lat). |
| postcode | string Instructors servicing this postcode. |
| suburb | string Instructors servicing this suburb. |
| location_id | integer Instructors mapped to this service location. |
| transmission | string Enum: "auto" "manual" "both" Instructor's transmission (a custom field — |
| gender | string Case-insensitive exact match. |
| language | string Instructor speaks this language. |
| nationality | string Case-insensitive exact match. |
| car | string Filter by the instructor's car. |
| available_date | string <date> Only instructors with free capacity on this date. |
| time_of_day | string Enum: "morning" "afternoon" "evening" Narrows |
| with_next | boolean Include each instructor's |
| cf | object Match arbitrary instructor custom fields, e.g. |
{- "success": true,
- "instructors": [
- {
- "id": 0,
- "name": "string",
- "gender": "string",
- "languages": [
- "string"
], - "transmission": "string",
- "bio": "string",
- "photo_url": "string",
- "service_areas": [
- {
- "suburb": "string",
- "postcode": "string",
- "state": "string",
- "radius_km": 0
}
]
}
]
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| transmission | string Enum: "auto" "manual" |
| type | string Enum: "lesson" "package" |
| instructor_id | integer Only the lessons/packages this instructor actually offers. |
{- "success": true,
- "courses": [
- {
- "id": 0,
- "name": "string",
- "price": 0,
- "currency": "AUD",
- "duration_minutes": 0,
- "transmission": "string",
- "is_package": true
}
]
}Bookable slots for an instructor on a date, honouring the weekly schedule, overrides, existing bookings and booking settings.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your Copy it from Settings → API Keys → “Integration details”, which shows the slug and the ready-made endpoint URL with a copy button. It is also in Settings → Company Profile. ⚠️ Do not derive it from the company name. It is not your display name, brand or product name, and it is not reliably a slugified version of them either — workspaces are often created under one name, or renamed later, while the slug stays as first issued. A workspace branded “Acme Halls” can legitimately have a slug that looks nothing like it. Guessing produces a plausible-looking URL that always fails. Copy it, don't infer it. An unknown slug returns |
| instructor_id required | integer |
| date required | string <date> |
| duration_minutes | integer [ 15 .. 480 ] Slot length to fit. Outside 15–480 returns 422. |