> ## Documentation Index
> Fetch the complete documentation index at: https://omni.fireflo.au/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /v1/catalogue/orders/{order_id}/confirm

> Confirm an order — the customer gets the account's confirmation on the order's channel.

Confirms an order. The customer is sent the account's confirmation reply — the one set in Catalogue's settings, with their name, the order number and the total filled in — on the channel the order came in on. If the channel can't send it, the order is confirmed all the same and its history says why the reply didn't go. Webhooks get `order.confirmed`. Asking again for the status it already has changes nothing and sends nothing.

<Note>Needs the `catalogue.orders:write` scope.</Note>

## Path parameters

| Field | Type | Required | Notes |
| :- | :- | :- | :- |
| `order_id` | string | Yes | The order's id. |

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.fireflo.au/v1/catalogue/orders/9d4e2b7a-1c3f-4a8e-b6d5-0f2e7c9a1b34/confirm" \
    -H "Authorization: Bearer $OMNI_API_KEY"
  ```

  ```python Python theme={null}
  import os

  import requests

  response = requests.post(
      "https://api.fireflo.au/v1/catalogue/orders/9d4e2b7a-1c3f-4a8e-b6d5-0f2e7c9a1b34/confirm",
      headers={"Authorization": f"Bearer {os.environ['OMNI_API_KEY']}"},
  )
  print(response.status_code, response.json())
  ```

  ```javascript Node theme={null}
  const response = await fetch("https://api.fireflo.au/v1/catalogue/orders/9d4e2b7a-1c3f-4a8e-b6d5-0f2e7c9a1b34/confirm", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.OMNI_API_KEY}` },
  });
  console.log(response.status, await response.json());
  ```
</CodeGroup>

## Response

`200 OK` — the order, now `confirmed`. `status` is `new`, `confirmed`, `declined`, `fulfilled` or `cancelled`. `source` is where it came from: `cart` (a WhatsApp cart), `agent` (an AI agent's draft, approved by a person), `person` (made by hand in the panel) or `api`. `channel` is the channel it came in on, where replies about it go. Each line keeps its own copy of the name and price, so a later change to the product doesn't rewrite it; `product` is the product's id, or `null` for a SKU the catalogue doesn't have. Money is in minor units.

```json theme={null}
{
  "id": "9d4e2b7a-1c3f-4a8e-b6d5-0f2e7c9a1b34",
  "number": 1043,
  "status": "confirmed",
  "source": "api",
  "channel": "whatsapp",
  "contact": {
    "id": "5b2f9e1c-8a3d-4c7e-9f61-2d4b7a0e3c85",
    "name": "Asha Menon",
    "phone": "+919876500102"
  },
  "items": [
    {
      "product": "3f8a2c1e-7b4d-4e6a-9c2f-1a5b8d7e6f40",
      "sku": "KUR-COT-IND-M",
      "name": "Cotton kurta — indigo, M",
      "quantity": 2,
      "unit_price_minor": 199900
    },
    {
      "product": "a71c5e93-2d8b-4f16-8e0a-6b9d3c2f1e57",
      "sku": "DUP-PHUL-RED",
      "name": "Phulkari dupatta — red",
      "quantity": 1,
      "unit_price_minor": 179900
    }
  ],
  "total_minor": 579700,
  "currency": "INR",
  "note": "Gift wrap, please.",
  "created_at": "2026-10-06T11:08:37+05:30",
  "updated_at": "2026-10-06T11:15:02+05:30"
}
```

## Errors

Every refusal is `{"error": {"code", "message", "field"}}`; `field` is there when one input is at fault.

| Status | Error code | When |
| :- | :- | :- |
| 404 | `not_found` | No order of this account's has that id. |
| 404 | `module_off` | The account doesn't have Catalogue on. |
| 403 | `scope_missing` | The key doesn't have the `catalogue.orders:write` scope. |

Any request can also be refused for its key, its account or its rate (`key_required`, `invalid_key`, `account_suspended`, `plan_excludes_api`, `address_not_allowed`, `rate_limited`); see [the overview](/api-reference/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.