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

# Recipe: Shopify (Flow)

> Fire the template send from Shopify Flow, with no code and no server of your own.

# Recipe: Shopify (Flow)

This is the guided recipe for the generic
[Template Messages](/en/outbound/cart-abandonment) contract: the same `POST`, walked
through step by step from Shopify.

Shopify does not call this API on its own, but **Shopify Flow** — the official automation
app, free — can: it fires on the abandoned cart and makes the `POST`. It is the route with
no code and no server of your own in the middle.

## Before you start

| Requirement | Where you sort it out |
| - | - |
| **Approved template** | With its exact technical name and `language` — `GET /v1/templates` lists them. |
| **API key** | With the `outbound:send` scope to send, plus `outbound:read` if you are going to check the status — see [Authentication](/en/authentication). |
| **Phone required at checkout** | Shopify → *Settings → Checkout*: **Customer contact method** set to "Phone number or email", and **Shipping address phone number** set to "Required". With no phone on the cart there is nobody to write to. |
| **Native recovery email turned off** | Shopify → *Marketing → Automations*: if WhatsApp takes over, disable the native "Abandoned checkout". Otherwise the customer gets two reminders for the same cart. |

## The workflow

1. **Trigger** — *Customer abandons checkout*.
2. **Condition** — `abandonment.customer.defaultPhoneNumber` **is not empty**. A checkout
   with no phone cannot be sent: cutting it here saves spending the call on a `422`.
3. **Action** — *Send HTTP request*, with method `POST`, the URL
   `https://api.ya.onl/v1/template-messages` and two headers: `X-API-Key` with your key and
   `Content-Type: application/json`.

## The body

```json theme={null}
{
  "event_id": "CART-{{ abandonment.id | split: '/' | last }}",
  "phone": "{{ abandonment.customer.defaultPhoneNumber.phoneNumber }}",
  "template": { "name": "YOUR_TEMPLATE", "language": "es" },
  "variables": {
    "1": "{{ abandonment.customer.firstName }}",
    "2": "{% for item in abandonment.abandonedCheckoutPayload.lineItems limit: 3 %}{{ item.quantity }}× {{ item.title | replace: '\"', '' }}{% unless forloop.last %}, {% endunless %}{% endfor %}"
  },
  "occurred_at": "{{ abandonment.createdAt }}"
}
```

| Field | What that line does |
| - | - |
| `event_id` | Trims Shopify's GID (`gid://shopify/Abandonment/774830424`) down to its last segment, which matches the field's charset, and the `CART-` prefix covers the 8-character minimum and gives you idempotency: if Flow retries, the customer does not get two messages. |
| `phone` | `defaultPhoneNumber.phoneNumber` already comes in E.164 (`+51987654321`), which is exactly what the field requires. |
| `template` | An object with your template's name and language, exactly as approved in Meta: replace `YOUR_TEMPLATE` and adjust `language`. |
| `variables` | By position, in your template's order: `"1"` the name, `"2"` the first three products. **Match the count to what the template requires** — a missing one is a `422`. The `replace` strips quotes out of the title, which would break the JSON. |
| `occurred_at` | `abandonment.createdAt` already carries an offset, and it is what switches on the freshness window: an old abandonment comes back `discarded` with reason `stale` instead of being sent late. |

<Note>
  **The recipe is generic.** The contract is the same from any platform able to make a
  `POST` — another ecommerce, your own backend, or an automation tool like Zapier or Make.
  Shopify Flow is only the guided example, because it solves the abandonment trigger
  without writing code.
</Note>

## Check that it went out

```bash theme={null}
curl https://api.ya.onl/v1/template-messages/CART-774830424 \
  -H "X-API-Key: yv_live_v1_your_api_key"
```

With the same key — as long as it has `outbound:read` — and the same `event_id` Flow built.
A `404` means the call never arrived: check the workflow's run history in Flow.


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