# How do I wire a voice agent to confirm COD orders, share status, and reschedule delivery?

A store webhook fires at the moment of truth -- order placed, out for delivery, delivery failed -- and your backend turns that into POST /v1/calls with an Idempotency-Key derived from the order id. There is no Shopify connector; this page is how you build one yourself.


You trigger the call from your own store's order events, not from anything VARTA
subscribes to: a webhook lands on your backend, your backend decides which agent and
which script the moment calls for, and your backend calls `POST /v1/calls`. **There is
no Shopify connector** -- Shopify's `orders/create` webhook is used below as one
concrete example of the trigger, but the pattern is the same for any storefront that
can call a webhook on an event.

## The three moments this covers

- **COD confirmation** -- right after an order is placed, before it ships, confirm the
  customer still wants a cash-on-delivery order and hasn't been targeted by a fraud
  wave of fake orders in their name.
- **Order status** -- a customer-initiated check, or a proactive "your order shipped"
  call.
- **Delivery rescheduling** -- the carrier reports a failed or upcoming attempt, and
  the agent asks the customer to pick a new window.

Each is a different agent (a different call flow you author in the studio), triggered
by a different store event, but they all go through the same integration shape.

## The call sequence

1. Your backend receives the store's webhook (Shopify's `orders/create`, or your
   platform's equivalent) and validates its signature.
2. It maps the order to an agent and builds the call context.
3. It calls `POST /v1/calls`, with the `Idempotency-Key` derived from the order id so a
   webhook retry -- which every store's webhook delivery will eventually do -- can't
   dial the same customer twice for the same order event.

```bash
curl -X POST "$VARTA_BASE_URL/calls" \
  -H "Authorization: Bearer $VARTA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cod-confirm-ORD-88213" \
  -d '{
    "agent_id": "ag_412",
    "to": "+9198xxxxxxx",
    "customer_name": "Rahul",
    "context": {"order_id": "ORD-88213", "cod_amount": 2350, "sku_summary": "1x running shoes, size 9"}
  }'
```

> **Agent ids are numeric and studio-assigned.** `ag_412` above is the shape the API
> actually issues: `/v1` strips the `ag_` prefix and parses the rest as an integer
> (`backend/app/api/v1/_ids.py:56-61`), so an author-chosen slug like
> `ag_cod_confirm` is rejected as malformed before any lookup happens. Use the id the
> studio gave your agent.

That request only *prepares* the call by default -- add `"dial": true` (and a
`trunk_id` if your tenant has **zero or more than one** trunk: zero leaves nothing to
default to, more than one leaves the choice ambiguous) once you want it to actually
ring.
See [Place a call](/docs/api/calls) for the full request/response shape and why the
`Idempotency-Key` matters here specifically: a duplicate COD-confirmation call to the
same customer about the same order is not a harmless retry, it is a second phone call
about money.

4. Poll `GET /v1/calls/{call_id}` for status, or listen for whatever your deployment
   uses to notify you the call ended.
5. Once the call is done, read back what the customer said -- confirmed, wants a
   different delivery window, wants to cancel -- from the session it ran on. The order
   status and reschedule flows follow the identical `POST /v1/calls` → poll → read-back
   shape, with a different `agent_id` and a `context` shaped for that script (a
   reschedule agent needs the carrier's offered windows in `context`, for instance).

## What you still have to build

- **The webhook receiver itself** -- endpoint, signature verification, retry handling,
  and the order → agent/context mapping. VARTA has no knowledge of your storefront's
  event shape.
- **Fraud or COD-risk logic upstream of the call** -- deciding *which* orders warrant a
  confirmation call is a business rule you own, not something `POST /v1/calls` decides.
- **Reading the outcome back into your OMS** -- VARTA records what happened on the
  call; writing "customer confirmed" or "customer wants Tuesday" back into your order
  management system is your integration to write.
- **Carrier-side rescheduling** -- the agent captures the customer's preferred window;
  actually moving the delivery slot with your logistics provider is a separate API call
  you make after the fact.
- **Consent and do-not-call handling** -- a customer who has opted out of calls for
  this order or account needs to be excluded before you ever reach `POST /v1/calls`.
