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

# Postman Collection

A Postman collection covering the Loop public API — every endpoint, grouped by resource, with
example request bodies drawn from the same OpenAPI specs that power this documentation.

<Card title="Download the collection" icon="download" href="/postman/loop-public-api.postman_collection.json">
  Import into Postman, then set your API key. The collection is self-contained — no separate
  environment file required.
</Card>

## Setup

1. In Postman, choose **Import** and select the downloaded file.
2. Open the collection's **Variables** tab.
3. Set `apiKey` to a key generated in [Developer Tools](https://admin.loopreturns.com/settings/developers).
4. Run **Setup & Auth → Who Am I** to confirm the key resolves to the expected shop, and to see the
   scopes it carries.

`baseUrl` is pre-set to `https://api.loopreturns.com/api/v1`. Authentication is configured at the
collection level as the `X-Authorization` header, so individual requests inherit it.

## Build order

Records must exist before anything that references them. Seeding a sandbox from empty, build in
this order:

| # | Create           | Requires                          |
| - | ---------------- | --------------------------------- |
| 1 | Locations        | —                                 |
| 2 | Customers        | —                                 |
| 3 | Products         | —                                 |
| 4 | Product Variants | a product                         |
| 5 | Inventories      | a variant **and** a location      |
| 6 | Orders           | a variant, a location, a customer |
| 7 | Collections      | products to add                   |

Locations are needed twice — once by inventory, once by order fulfilment.

<Warning>
  **An order is only returnable if it is fulfilled.** The API accepts an order with no
  `fulfillments` and returns `200`, but nothing on it can be returned — draft-return testing then
  dead-ends with an empty eligible-items list and no error explaining why.
</Warning>

## Referencing records

Every reference accepts either Loop's global identifier or your own external ID. Sending both is a
validation error, not a preference:

```json theme={null}
"customer": { "external_id": "CUST-1001" }         ✅
"customer": { "id": "935084295154958336" }          ✅
"customer": { "id": "935…", "external_id": "…" }    ❌ 422
```

Most resources also expose dedicated `/external/{externalId}` routes for `GET` and `DELETE`.

<Note>
  Loop's identifiers are 18–19 digit integers that exceed JavaScript's safe integer range, so
  `JSON.parse` silently corrupts them — including Postman's own response viewer. Every request in
  this collection sends `X-Loop-Global-Identifier-Type: string`, so identifiers arrive as strings
  and stay intact. If you drop that header in your own client, address records by your
  `external_id` instead.
</Note>

## Draft Returns

Draft Returns is a state machine. Every response's `_templates` enumerates which actions are legal
next — drive your integration from those rather than hardcoding a sequence, since what is available
changes with shop configuration.

<Note>
  `_templates` only appears in the HAL-FORMS representation, so every request in the Draft Returns
  folder sends `Accept: application/prs.hal-forms+json`. `GET /draft-returns` requires it and
  returns `422 unsupported-feature` without it; the other endpoints fall back to plain REST JSON and
  silently omit `_templates`, which is easier to miss.
</Note>

The folder is ordered as the journey runs: Create & Inspect → Returning Items → Outcome →
Shop Now Cart → Shipping & Customer → Payment → Finalize & Submit.

## Testing webhooks

`Webhooks → Get Sample Payloads` returns example payloads for each topic, so you can build and test
handlers without triggering real events.
