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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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.
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}.
Your approved sender IDs, templates and PE ID are listed in Marketing → SMS Gateway (DLT Registration / Sender IDs / Templates).
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your 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 (Marketing → SMS Gateway → Sender IDs). Must be the sender the |
| template_id | string <= 64 characters Registered DLT template id. Omit it and Indian carriers drop the SMS silently. |
| pe_id | string <= 64 characters DLT principal entity (PE) id, from Marketing → SMS Gateway → DLT Registration. |
| 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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. |
{- "success": true,
- "available": true,
- "reason": "string",
- "slots": [
- {
- "start": "09:00",
- "end": "11:00"
}
]
}The custom-field definitions available for filtering instructors — use the returned key values with the cf[...] query parameter on GET /instructors to build facets without hard-coding them.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
{- "success": true,
- "fields": [
- {
- "key": "transmission",
- "label": "string",
- "type": "string",
- "options": [
- { }
]
}
]
}Returns the stored name for a matching email or phone so the widget can greet a returning student and pre-fill the form. Pass email or phone.
⚠️ This confirms whether a given email/phone is a customer of the school and reveals their name. Its only gate is your key's allowed-origins list, so treat the key as origin-locked and do not ship it anywhere you would not accept that lookup being run.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
string <email> Exact match. | |
| phone | string Digits are extracted, so formatting is ignored. |
{- "success": true,
- "customer": {
- "name": "string"
}
}Maps browser geolocation to a suburb you can feed back into GET /instructors?suburb=.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
| lat required | number [ -90 .. 90 ] |
| lng required | number [ -180 .. 180 ] |
{- "success": false,
- "message": "Invalid API credentials, or the company was not found."
}Prices the travel component for a test-day pickup before booking, so the widget can show it up front. The same charge is recomputed server-side when the booking is created.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
| location_id required | integer The test centre. Must exist, else 422. |
| lat required | number [ -90 .. 90 ] Pickup latitude. |
| lng required | number [ -180 .. 180 ] Pickup longitude. |
{- "success": true,
- "currency": "AUD",
- "travel_distance_km": 0,
- "travel_charge": 0
}Buys a lesson package for a customer, optionally scheduling its lessons up front and optionally taking a deposit (pay_amount) rather than the full price. Supply return_url+cancel_url to start online payment and receive payment_data.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
required | object (SchoolCustomer) Buyer details for the schools flows. |
| product_id required | integer Must be a lesson package, else 422. |
| lessons | Array of objects <= 50 items Optional lessons to schedule now. Each must be at least 15 minutes. |
| pay_amount | number or null >= 0 Deposit. Omit to charge the full package price. |
| return_url | string or null <uri> |
| cancel_url | string or null <uri> |
{- "customer": {
- "name": "string",
- "phone": "string",
- "email": "user@example.com",
- "address": "string",
- "city": "string",
- "state": "string",
- "postcode": "string"
}, - "product_id": 0,
- "lessons": [
- { }
], - "pay_amount": 0,
}{- "success": true,
- "message": "string",
- "booking": {
- "id": 0,
- "booking_number": "BK-000012",
- "status": "confirmed",
- "payment_status": "paid",
- "booking_type": "string",
- "test_time": "14:30",
- "lesson_before_minutes": 0,
- "pickup_required": true,
- "travel_distance_km": 0,
- "travel_charge": 0,
- "booking_date": "2019-08-24",
- "start_time": "10:00",
- "end_time": "12:00",
- "duration_minutes": 0,
- "total_amount": 0,
- "currency": "AUD",
- "service_location_id": 0,
- "product_id": 0,
- "instructor": {
- "id": 0,
- "name": "string"
}
}, - "payment": {
- "required": true,
- "amount": 0,
- "currency": "AUD",
- "status": "partial",
- "gateway": "stripe",
- "payment_url": "string",
- "payment_data": { },
- "invoice_id": 0,
- "travel_charge": 0,
- "online_payment_enabled": true
}
}Orders one or more services from an instructor's menu (up to 20 items), optionally with a deposit. Supply return_url+cancel_url to start online payment.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
required | object (SchoolCustomer) Buyer details for the schools flows. |
| instructor_id required | integer |
| items required | Array of objects [ 1 .. 20 ] items Services from this instructor's menu. An unavailable service returns 422. |
| pay_amount | number or null >= 0 Deposit. Omit to charge the full total. |
| payment_method | string or null Enum: "card" "bank_transfer" |
| return_url | string or null <uri> |
| cancel_url | string or null <uri> |
{- "customer": {
- "name": "string",
- "phone": "string",
- "email": "user@example.com",
- "address": "string",
- "city": "string",
- "state": "string",
- "postcode": "string"
}, - "instructor_id": 0,
- "items": [
- { }
], - "pay_amount": 0,
- "payment_method": "card",
}{- "success": true,
- "message": "string",
- "booking": {
- "id": 0,
- "booking_number": "BK-000012",
- "status": "confirmed",
- "payment_status": "paid",
- "booking_type": "string",
- "test_time": "14:30",
- "lesson_before_minutes": 0,
- "pickup_required": true,
- "travel_distance_km": 0,
- "travel_charge": 0,
- "booking_date": "2019-08-24",
- "start_time": "10:00",
- "end_time": "12:00",
- "duration_minutes": 0,
- "total_amount": 0,
- "currency": "AUD",
- "service_location_id": 0,
- "product_id": 0,
- "instructor": {
- "id": 0,
- "name": "string"
}
}, - "payment": {
- "required": true,
- "amount": 0,
- "currency": "AUD",
- "status": "partial",
- "gateway": "stripe",
- "payment_url": "string",
- "payment_data": { },
- "invoice_id": 0,
- "travel_charge": 0,
- "online_payment_enabled": true
}
}Match/create the customer and create the booking. If return_url+cancel_url are supplied and payment is due, payment is initiated and payment_url returned. Prices come from your catalogue server-side.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
required | object (SchoolCustomer) Buyer details for the schools flows. |
| instructor_id required | integer Must exist — an unknown id is 422, not 404. |
| product_id | integer or null |
| service_location_id | integer or null |
| booking_package_id | integer or null Book against a pre-paid package (no payment). 403 if the package belongs to another customer. |
| booking_date required | string <date> Today or later — a past date is rejected. |
| start_time | string or null^\d{2}:\d{2}$ 24-hour HH:MM. Required unless |
| end_time | string or null^\d{2}:\d{2}$ 24-hour HH:MM. Must be after |
| duration_minutes | integer or null [ 15 .. 480 ] |
| test_time | string or null^\d{2}:\d{2}$ 24-hour HH:MM. Sending this makes it a DRIVING-TEST booking; the block is derived from this time. |
| lesson_before_minutes | integer or null Enum: 0 45 60 90 120 Warm-up lesson immediately before the test. |
| pickup_required | boolean or null Test-day pickup. The pickup coordinates drive the travel charge. |
| pickup_lat | number or null [ -90 .. 90 ] |
| pickup_lng | number or null [ -180 .. 180 ] |
| pickup_address | string or null <= 500 characters |
| dropoff_address | string or null <= 500 characters |
| student_notes | string or null <= 1000 characters |
| return_url | string or null <uri> Supply BOTH urls to initiate online payment immediately — the response then carries |
| cancel_url | string or null <uri> |
{- "customer": {
- "name": "string",
- "phone": "string",
- "email": "user@example.com",
- "address": "string",
- "city": "string",
- "state": "string",
- "postcode": "string"
}, - "instructor_id": 0,
- "product_id": 0,
- "service_location_id": 0,
- "booking_package_id": 0,
- "booking_date": "2019-08-24",
- "start_time": "10:00",
- "end_time": "12:00",
- "duration_minutes": 15,
- "test_time": "14:30",
- "lesson_before_minutes": 0,
- "pickup_required": true,
- "pickup_lat": -90,
- "pickup_lng": -180,
- "pickup_address": "string",
- "dropoff_address": "string",
- "student_notes": "string",
}{- "success": true,
- "message": "string",
- "booking": {
- "id": 0,
- "booking_number": "BK-000012",
- "status": "confirmed",
- "payment_status": "paid",
- "booking_type": "string",
- "test_time": "14:30",
- "lesson_before_minutes": 0,
- "pickup_required": true,
- "travel_distance_km": 0,
- "travel_charge": 0,
- "booking_date": "2019-08-24",
- "start_time": "10:00",
- "end_time": "12:00",
- "duration_minutes": 0,
- "total_amount": 0,
- "currency": "AUD",
- "service_location_id": 0,
- "product_id": 0,
- "instructor": {
- "id": 0,
- "name": "string"
}
}, - "payment": {
- "required": true,
- "amount": 0,
- "currency": "AUD",
- "status": "partial",
- "gateway": "stripe",
- "payment_url": "string",
- "payment_data": { },
- "invoice_id": 0,
- "travel_charge": 0,
- "online_payment_enabled": true
}
}Initiate payment for a pending, unpaid booking that this widget created. Returns payment_url/payment_data to redirect to; the booking is confirmed by the gateway webhook on success. The amount is derived server-side — there is no amount or payment-mode field. Requires a configured gateway for the currency, else 422.
Only widget-created, still-pending bookings are payable: handing this any other booking id in the tenant returns 403, not a checkout.
| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
| id required | string Opaque resource identifier. |
| return_url required | string <uri> |
| cancel_url required | string <uri> |
{
}{- "success": true,
- "message": "string",
- "booking": {
- "id": 0,
- "booking_number": "BK-000012",
- "status": "confirmed",
- "payment_status": "paid",
- "booking_type": "string",
- "test_time": "14:30",
- "lesson_before_minutes": 0,
- "pickup_required": true,
- "travel_distance_km": 0,
- "travel_charge": 0,
- "booking_date": "2019-08-24",
- "start_time": "10:00",
- "end_time": "12:00",
- "duration_minutes": 0,
- "total_amount": 0,
- "currency": "AUD",
- "service_location_id": 0,
- "product_id": 0,
- "instructor": {
- "id": 0,
- "name": "string"
}
}, - "payment": {
- "required": true,
- "amount": 0,
- "currency": "AUD",
- "status": "partial",
- "gateway": "stripe",
- "payment_url": "string",
- "payment_data": { },
- "invoice_id": 0,
- "travel_charge": 0,
- "online_payment_enabled": true
}
}| company required | string Example: acme-traders Your company (workspace) slug — the same value as your An unknown slug returns |
| id required | string Opaque resource identifier. |
{- "success": true,
- "booking": {
- "id": 0,
- "booking_number": "BK-000012",
- "status": "confirmed",
- "payment_status": "paid",
- "booking_type": "string",
- "test_time": "14:30",
- "lesson_before_minutes": 0,
- "pickup_required": true,
- "travel_distance_km": 0,
- "travel_charge": 0,
- "booking_date": "2019-08-24",
- "start_time": "10:00",
- "end_time": "12:00",
- "duration_minutes": 0,
- "total_amount": 0,
- "currency": "AUD",
- "service_location_id": 0,
- "product_id": 0,
- "instructor": {
- "id": 0,
- "name": "string"
}
}
}