# POST /partner/dispatch/shipments

Open a B2B order for a distributor, replayable on the order reference. Requires the dispatch:write scope.

Source: https://docs.sealtrust.io/en/reference/post-partner-dispatch-shipments/

---

You open a B2B order: the order reference from your ERP or your logistics
provider, and the distributor who receives it. Units are then added to it as
the order is picked. The whole flow is in the guide [Tie each unit to its order](/en/expedition-b2b/).

The full address is `https://api.sealtrust.io/v1/partner/dispatch/shipments`.

This call can be replayed. The same `order_ref` returns the same shipment, with
code 200 and `created` set to `false`. The same `order_ref` for another
distributor is refused with 409: we never rewrite where units went.

## Authorization

API key in the `Authorization` header, `Bearer` format, with the
`dispatch:write` scope. A key without it gets a 403 whose message names the
missing scope. The plan of the key's brand must include API access, and the
shipment's brand must be on the Compliance + Identity offer.

```http
Authorization: Bearer votre_clef
```

## Rate limit

The same as the other partner routes: one counter per key and one for the sum
of your brand's keys, 120 calls per 60-second window by default. Every call that
writes takes 1 unit of the key's daily quota, whatever the number of units it
carries.

## Request body

`application/json`. Any unknown field gets the request refused with 422.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `order_ref` | `string` | yes | Your order number, 1 to 100 characters. Unique within your brand. |
| `distributor_code` | `string` | yes | The distributor's code, an active retailer of type "Distributor". |
| `ship_date` | `string` | no | Ship date, `YYYY-MM-DD`. |
| `ship_to_country` | `string` | no | Ship-to country, two-letter ISO code. Absent, the distributor's country. |
| `brand_code` | `string` | no | With a reseller key, the public code of one of your client brands. Absent, the key's brand. |

The territory the alert checks is the distributor's, never `ship_to_country`,
which is informative only.

## Example request

```bash
curl -i -X POST "https://api.sealtrust.io/v1/partner/dispatch/shipments" \
  -H "Authorization: Bearer st_live_0000000000000000000000000000000000000000000000" \
  -H "Content-Type: application/json" \
  -d '{"order_ref": "SO-2026-1042", "distributor_code": "DIST-DE", "ship_date": "2026-10-09"}'
```

## Example response

HTTP 201 on creation, 200 when the order already existed.

```json
{
  "id": 318,
  "brand_id": 42,
  "order_ref": "SO-2026-1042",
  "status": "open",
  "ship_date": "2026-10-09",
  "ship_to_country": "DE",
  "distributor": {
    "id": 77,
    "code": "DIST-DE",
    "name": "Acme Distribution GmbH",
    "country": "DE",
    "territory_countries": ["DE", "AT"]
  },
  "units_allocated": 0,
  "created_by": "api-key:st_live_000",
  "created_at": "2026-10-09T07:12:44.120391+00:00",
  "closed_at": null,
  "created": true
}
```

## Errors

| Code | Condition | What to do |
| --- | --- | --- |
| 401 | Key missing, malformed or unknown. | Send `Authorization: Bearer <your key>` with the whole key. |
| 403 | The key lacks the `dispatch:write` scope. Message `Missing required scopes: dispatch:write`. | Create a key that carries this scope. |
| 403 | The brand is on the Compliance offer. `detail.code` is `OFFER_EXCLUDES_IDENTITY` and `detail.feature` is `dispatch`. Nothing is recorded. | Move to the Compliance + Identity offer. Retrying changes nothing. |
| 429 | Rate limit or daily quota reached. | Wait the number of seconds in `Retry-After`, or midnight UTC for the quota. |
| 404 | No active distributor of your brand has this code. `detail.code` is `distributor_not_found`. | Create the distributor in the console, Retailers tab. |
| 409 | This `order_ref` already exists for another distributor. `detail.code` is `order_ref_other_distributor`. | Check the order reference. |
| 422 | The retailer exists but is not of type distributor (`retailer_is_not_a_distributor`), or the body is invalid: a control character, or an `order_ref` starting with `=`, `+`, `-` or `@`, which a spreadsheet would run as a formula. | Change its type in the console, or fix the body. |
