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

# Return webhooks

> PII-free marketplace return and refund outcomes with SKU-level lines.

Returns are their own versioned resource. They are not embedded in
`order.updated` because a return can begin after fulfillment and can be approved,
rejected, received, refunded, or corrected independently of the order status.

## Events

| Event                   | Emitted when                                                                          |
| ----------------------- | ------------------------------------------------------------------------------------- |
| `return.created`        | A normalized return and its current lines first commit                                |
| `return.updated`        | Amounts, identifiers, or SKU-level lines change without a canonical status transition |
| `return.status.changed` | The provider-neutral return status changes                                            |

All three use `schemaVersion: "2026-08-29"`, the standard event ID,
`resourceVersion`, source identity, and complete `data.return` snapshot.

## Statuses

```text theme={null}
requested | approved | in_transit | received | completed | rejected | cancelled | unknown
```

`marketplaceStatus` preserves the provider label. Build business behavior from
the normalized `status`; retain the provider label only for audit and support.

## Return snapshot

| Field                                 | Meaning                                      |
| ------------------------------------- | -------------------------------------------- |
| `id`                                  | Stable OmniCommerce return UUID              |
| `orderId`                             | Matched OmniCommerce order UUID, or `null`   |
| `marketplace`, `accountId`            | Provider and exact connected store identity  |
| `externalReturnId`, `externalOrderId` | Marketplace return and order identity        |
| `status`, `marketplaceStatus`         | Normalized and original lifecycle status     |
| `refundAmount`                        | Return-level decimal-string money, or `null` |
| `itemCount`, `quantity`, `items`      | Current SKU-level return outcome             |
| `sourceCreatedAt`, `sourceUpdatedAt`  | Marketplace timestamps when supplied         |
| `createdAt`, `updatedAt`              | OmniCommerce record timestamps               |

Each line contains stable internal and provider line IDs, matched `productId`,
marketplace product/variant IDs, SKU aliases, quantity, status, and line refund
money. Buyer names, emails, phones, and delivery addresses are excluded.

## Example status change

```json theme={null}
{
  "schemaVersion": "2026-08-29",
  "id": "evt_53c9e0d6fd784aacb84de9863e2f82f7",
  "type": "return.status.changed",
  "occurredAt": "2026-08-29T08:15:00.000Z",
  "publishedAt": "2026-08-29T08:15:01.000Z",
  "organizationId": "org_123",
  "resourceVersion": 3,
  "source": {
    "system": "marketplace",
    "marketplace": "lazada",
    "accountId": "seller-123",
    "providerEventId": null,
    "providerEventType": null
  },
  "subject": {
    "type": "return",
    "id": "11111111-1111-4111-8111-111111111111",
    "externalId": "665434301169671",
    "externalNumber": null
  },
  "data": {
    "return": {
      "id": "11111111-1111-4111-8111-111111111111",
      "orderId": "22222222-2222-4222-8222-222222222222",
      "marketplace": "lazada",
      "accountId": "seller-123",
      "externalReturnId": "665434301169671",
      "externalOrderId": "164962091069671",
      "status": "completed",
      "marketplaceStatus": "REFUND_SUCCESS",
      "country": "SG",
      "currency": "SGD",
      "refundAmount": { "amount": "57.1", "currency": "SGD" },
      "itemCount": 1,
      "quantity": 1,
      "items": [
        {
          "id": "33333333-3333-4333-8333-333333333333",
          "productId": "44444444-4444-4444-8444-444444444444",
          "externalReturnItemId": "665434301269671",
          "marketplaceItemId": "13691971630",
          "marketplaceVariantId": "124573183081",
          "sku": "BX2200MI-MS",
          "sellerSku": "BX2200MI-MS",
          "shopSku": null,
          "name": "Linen wrap dress",
          "status": "REFUND_SUCCESS",
          "quantity": 1,
          "refundAmount": { "amount": "57.1", "currency": "SGD" }
        }
      ],
      "sourceCreatedAt": "2026-08-28T04:00:00.000Z",
      "sourceUpdatedAt": "2026-08-29T08:15:00.000Z",
      "createdAt": "2026-08-28T04:00:02.000Z",
      "updatedAt": "2026-08-29T08:15:00.000Z"
    },
    "previousStatus": "approved",
    "status": "completed",
    "marketplacePreviousStatus": "REFUND_APPROVED",
    "marketplaceStatus": "REFUND_SUCCESS",
    "changedFields": ["status", "marketplaceStatus", "refundAmount", "items"]
  }
}
```

## Pull reconciliation

Use `GET /api/v1/returns` with `returns:read` for bootstrap or reconciliation.
Filter by marketplace, exact account, external order ID, or `updatedSince`, and
follow the opaque cursor. Use `GET /api/v1/returns/{returnId}` for one resource.

Consumer rules are the same as other versioned webhooks: deduplicate by event
`id`, apply only a newer `resourceVersion` for one `subject.id`, replace from
the complete snapshot, and ignore unknown additive fields.
