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

# Add Recipient

> Add an address that receives merchant notification emails for a store

Add a merchant notification recipient to a store. Each store can have up to **5 recipients**. A new recipient's 9 event toggles **inherit the store's current `notify*` settings** (any key the store never set counts as subscribed), and `isPrimary` is always `false`. An event you already turned off therefore stays off — adding a recipient never resumes it.

Inheritance happens **once, at creation**: all 9 keys are written at that moment, so later changes to the store's `notify*` no longer affect existing recipients — use `update-recipient` instead. For the same reason, a second recipient inherits the store's current values rather than the first recipient's choices, and re-adding a removed address is a fresh inheritance, not a restore.

<Warning>
  While a store has no explicit recipient, the list shows a synthesized fallback entry (`isPrimary: true`) carrying the store owner's account email, and notifications go there. **Adding the first explicit recipient makes that fallback disappear** — from then on only the configured addresses receive notifications.
</Warning>

```
POST /v1/actions/store-notification-recipient/add-recipient
```

**Authentication:** API Key (owner or admin role required)

## Request Body

| Field     | Type   | Required | Description                                                                                                                                                   |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storeId` | string | Yes      | Store ID (Short ID format `STO_xxx`)                                                                                                                          |
| `email`   | string | Yes      | Recipient address. Normalized with `lower(trim())` before storage, so addresses differing only by case or surrounding whitespace count as the same recipient. |

## Example Request

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST https://api.waffo.com/v1/actions/store-notification-recipient/add-recipient \
    -H "Content-Type: application/json" \
    -H "X-Merchant-Id: $WAFFO_MERCHANT_ID" \
    -H "X-Signature: ..." \
    -d '{
      "storeId": "STO_2aUyqjCzEIiEcYMKj7TZtw",
      "email": "ops@acme.com"
    }'
  ```

  ```javascript JavaScript theme={"system"}
  const response = await fetch(
    "https://api.waffo.com/v1/actions/store-notification-recipient/add-recipient",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Merchant-Id": process.env.WAFFO_MERCHANT_ID,
        "X-Signature": signature,
      },
      body: JSON.stringify({
        storeId: "STO_2aUyqjCzEIiEcYMKj7TZtw",
        email: "ops@acme.com",
      }),
    },
  );

  const { data } = await response.json();
  ```
</CodeGroup>

## Success Response (200)

```json theme={"system"}
{
  "data": {
    "recipient": {
      "id": "11111111-2222-3333-4444-555555555555",
      "storeId": "STO_2aUyqjCzEIiEcYMKj7TZtw",
      "email": "ops@acme.com",
      "isPrimary": false,
      "preferences": {
        "notifyNewOrders": true,
        "notifyNewSubscriptions": true,
        "notifySubscriptionCanceled": true,
        "notifySubscriptionRenewed": true,
        "notifySubscriptionEnded": true,
        "notifySubscriptionPastDue": true,
        "notifySubscriptionUncanceled": true,
        "notifySubscriptionPlanChanged": true,
        "notifyChargeback": true
      },
      "createdAt": "2026-08-28T00:00:00.000Z"
    }
  }
}
```

<Note>
  The returned `recipient.id` is a UUID, not a Short ID. Treat it as an opaque string and pass it back as `recipientId` to `update-recipient` and `remove-recipient`.
</Note>

## Response Fields

| Field         | Type    | Description                                                                                            |
| ------------- | ------- | ------------------------------------------------------------------------------------------------------ |
| `id`          | string  | Recipient UUID. The fallback entry instead uses a sentinel of the form `OWNER_<storeId>`               |
| `storeId`     | string  | Owning store Short ID                                                                                  |
| `email`       | string  | Normalized recipient address                                                                           |
| `isPrimary`   | boolean | `false` for every recipient added through this endpoint; only the synthesized fallback entry is `true` |
| `preferences` | object  | The 9 event toggles, inherited from the store's current `notify*` at creation                          |
| `createdAt`   | string  | Creation timestamp (ISO 8601)                                                                          |

## Errors

> **Retry policy:** Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).

| Status | `errors[0].message`                                               | What it means                                                                     | Recommended handling                                        |
| ------ | ----------------------------------------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| 400    | `Missing required field: storeId`                                 | `storeId` was not provided                                                        | Fix the request body, resubmit                              |
| 400    | `Expected format: STO_xxx, got "..."`                             | `storeId` Short ID could not be decoded                                           | Fix the `storeId` format, resubmit                          |
| 400    | `Invalid email format`                                            | `email` is not a valid address                                                    | Fix the address, resubmit                                   |
| 400    | `Notification recipient limit reached (max 5 per store)`          | Store already has 5 recipients                                                    | Remove an existing recipient first                          |
| 401    | `Missing merchantId in request context`                           | API Key authentication did not resolve a merchant                                 | Verify API Key headers and signature                        |
| 403    | `Not authorized to manage notification recipients for this store` | Merchant is not `owner` or `admin` of the store                                   | Verify the merchant's role on this store                    |
| 409    | `Recipient with this email already exists for this store`         | The normalized address is already a recipient, or a concurrent write won the race | Update the existing recipient instead of adding a duplicate |
| 500    | `Internal server error`                                           | Unexpected server-side failure                                                    | Retry with exponential backoff (start 5s, max 3 attempts)   |
