Skip to content

API

Orders

Turn a WhatsApp conversation into a confirmed order: stock is reserved, the customer is recognised or created, and — where the company has switched it on — the courier is booked without anyone opening the order.

Create an order

POST/orders

Send JSON with Content-Type: application/json, up to 32 KB.

curl -X POST "https://www.chatcom.in/api/v1/urbanchat/orders" \
  -H "X-API-KEY: $UC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "customer": {
    "name": "Anjali Menon",
    "phone": "+91 98765 43210",
    "email": "anjali@example.com"
  },
  "items": [
    {
      "product_id": "TSHIRT-RED-M",
      "quantity": 2
    },
    {
      "product_id": "TSHIRT-BLU-L",
      "quantity": 1
    }
  ],
  "external_reference": "wa-conv-8f2c1e-order-1",
  "notes": "Gift wrap, please.",
  "delivery_address": {
    "line1": "12/4 MG Road, Ravipuram",
    "line2": "Opposite the bus stop",
    "city": "Kochi",
    "pincode": "682016"
  },
  "payment": "prepaid",
  "payment_reference": "UPI 412345678901"
}'

Body

customer.namestringrequired
Up to 120 characters.
customer.phonestringrequired
Any format. The customer with this number is used, or created if there is none. Must be a number WhatsApp can reach.
customer.emailstring
Saved only when the customer is new. An email already on file is never changed.
itemsarrayrequired
1–50 lines. The same product twice is merged into one line.
items[].product_idstringrequired
A variant’s sku (recommended), variant_id or barcode, from the catalogue.
items[].quantitynumber | stringrequired
Greater than zero, up to three decimal places. 2 and "2" are the same.
external_referencestringrequired
Your unique id for this order, up to 100 characters. See Idempotency below.
notesstring
Up to 500 characters, shown to staff on the order.
delivery_addressobject
Where this order goes. Strongly recommended — see Delivery below.
delivery_address.line1stringrequired
House, street and area.
delivery_address.line2string
Landmark or second line.
delivery_address.citystringrequired
Town or city.
delivery_address.pincodestringrequired
Six-digit Indian PIN code.
delivery_address.statestring
Optional: worked out from the PIN. Needed only for the few PINs two states share.
delivery_address.namestring
The recipient, when not the customer.
delivery_address.phonestring
A phone for the courier, when not the customer’s.
payment"cod" | "prepaid"
cod if the courier should collect the amount on delivery; prepaid (the default) if it is already paid.
payment_referencestring
For a prepaid order, the payment’s own reference — a UPI transaction id, for example. Shown to staff on the order.

Response

201 Created — the order exists, is confirmed, and its stock is reserved.amount is the total including GST.

201 Created
{
  "data": {
    "order_id": "cmg5a9d3k0007ab12cd34ef56",
    "order_number": "SO-2627-0042",
    "order_status": "confirmed",
    "amount": "1623.30",
    "currency": "INR",
    "created_at": "2026-10-13T07:42:11.000Z",
    "external_reference": "wa-conv-8f2c1e-order-1",
    "items": [
      {
        "sku": "TSHIRT-RED-M",
        "name": "Cotton T-shirt (Red / M)",
        "quantity": "2",
        "unit_price": "499.00",
        "line_total": "1047.90"
      },
      {
        "sku": "TSHIRT-BLU-L",
        "name": "Cotton T-shirt (Blue / L)",
        "quantity": "1",
        "unit_price": "549.00",
        "line_total": "576.45"
      }
    ],
    "payment": "prepaid",
    "delivery_address": {
      "name": null,
      "line1": "12/4 MG Road, Ravipuram",
      "line2": "Opposite the bus stop",
      "city": "Kochi",
      "state": "Kerala",
      "pincode": "682016",
      "phone": null
    }
  }
}

Idempotency and retries

external_reference makes order creation safe to retry. Use something unique to the order in your system — the conversation id plus a counter works well.

  • A request with a reference already used answers 200 with "duplicate": true and the original order. Nothing new is created.
  • After a timeout or a 500, retry with the same reference. If the first attempt got far enough to create the order, the retry finishes it instead of creating another.
  • A new order for the same customer needs a new reference.

Delivery and shipping

  • delivery_address is where this order is shipped, even if the customer’s record holds a different address. A new customer, or one with no address on file, gets it saved to their record too; an address already on file is never overwritten from a chat.
  • Where the company has turned on automatic booking, the courier is booked as soon as the order is confirmed. An order with no usable address is still created and confirmed, but waits for someone to add one — so send delivery_address to keep it hands-free.
  • For a PIN code that two states share, a missing or contradicting state is refused with 400 validation_failed naming delivery_address.state.

Errors

400validation_failed
A missing or malformed field, or a phone number that cannot be used. details lists { path, message }.
404not_found
An item that does not exist or is not for sale. details lists the product_ids.
409insufficient_stock
Not enough stock. details gives requested and available for each short item. Nothing was created.
413 / 415validation_failed
Body over 32 KB, or not JSON.
422unprocessable
The company has no active stock location to sell from.
500internal
Our fault. Retry with the same external_reference.

Look up an order

GET/orders/{reference}?phone={phone}

{reference} is the order number (SO-2627-0042), the order_id, or your external_reference. The response adds the customer, the lines, the shipment with its tracking link, and the invoice with what is still due. Draft orders are never returned.

curl "https://www.chatcom.in/api/v1/urbanchat/orders/SO-2627-0042?phone=%2B919876543210" \
  -H "X-API-KEY: $UC_API_KEY"
200 OK
{
  "data": {
    "order_id": "cmg5a9d3k0007ab12cd34ef56",
    "order_number": "SO-2627-0042",
    "order_status": "shipped",
    "status_label": "Shipped",
    "amount": "1623.30",
    "currency": "INR",
    "order_date": "2026-10-13T00:00:00.000Z",
    "external_reference": "wa-conv-8f2c1e-order-1",
    "customer": {
      "name": "Anjali Menon",
      "phone": "+919876543210"
    },
    "items": [
      {
        "sku": "TSHIRT-RED-M",
        "name": "Cotton T-shirt (Red / M)",
        "quantity": "2",
        "unit_price": "499.00",
        "line_total": "1047.90"
      },
      {
        "sku": "TSHIRT-BLU-L",
        "name": "Cotton T-shirt (Blue / L)",
        "quantity": "1",
        "unit_price": "549.00",
        "line_total": "576.45"
      }
    ],
    "shipment": {
      "awb": "EZ123456789IN",
      "courier": "India Post",
      "status": "in_transit",
      "status_label": "In transit",
      "tracking_url": "https://…",
      "delivered_at": null
    },
    "invoice": {
      "invoice_number": "INV-2627-0042",
      "payment_status": "paid",
      "total": "1623.30",
      "amount_due": "0.00"
    }
  }
}

Statuses

order_statusstring
confirmed, packed, shipped, delivered, cancelled or returned. status_label is the same in words, for showing a customer.
shipment.statusstring | null
The courier’s latest state: pending, booked, picked_up, in_transit, out_for_delivery, delivered, rto (returning to sender), cancelled or failed. shipment is null until a parcel is booked.
invoice.payment_statusstring
unpaid, partial, paid or overdue. amount_due is what is still owed.