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

# Status updates

> Push fulfillment events from your side back to LMN.

## POST /v1/orders/\{id}/status

After LMN's responsibility ends at vessel departure (Bill of Lading issued), only the partner can confirm what happens next. This endpoint accepts the two partner-owned status transitions: `in_transit → customs` and `customs → delivered`.

Sandbox follows the same permission model. Use `POST /v1/orders/{id}/sandbox-status` when you need to simulate LMN-owned lifecycle states for testing.

```bash theme={null}
curl -X POST \
  -H "x-api-key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "delivered",
    "occurred_at": "2026-06-15T12:00:00+01:00",
    "notes": "Delivered to dealer at Ikeja, Lagos"
  }' \
  https://api.lmnauto.com/v1/orders/01HXYZ.../status
```

| Field         | Type                 | Required | Description                                                                                                                                                                                                                                                                                                                             |
| ------------- | -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`      | enum                 | yes      | `customs` or `delivered`. No other values are partner-writable through this endpoint.                                                                                                                                                                                                                                                   |
| `occurred_at` | ISO 8601 with offset | no       | When the event happened in the real world, in the event's local offset (e.g., `+01:00` for Lagos events). Accepted for forward compatibility but **not currently persisted** — today LMN's timeline records when the push reached the API. Send it anyway: persistence is planned, and clients that already send it won't need changes. |
| `notes`       | string \| null       | no       | Free-text context for ops. Accepted but **not currently persisted** (same as `occurred_at`).                                                                                                                                                                                                                                            |

The legacy `fulfillment_detail` field has been removed. Send `status` instead.

### Allowed partner-driven transitions

| Current status | Request             | Result                                                                                     |
| -------------- | ------------------- | ------------------------------------------------------------------------------------------ |
| `in_transit`   | `status: customs`   | Transitions to `customs`.                                                                  |
| `customs`      | `status: delivered` | Transitions to `delivered`. **Mandatory** — partner MUST push this to close the lifecycle. |

LMN-owned statuses (`secondary_inspection_in_progress`, `secondary_inspection_ready`, `acquiring`, `secured`, `export_processing`, `in_transit`) cannot be set by the partner; attempting them returns `403 invalid_status_transition` with `details.reason: "partner_not_authorized"`. Out-of-sequence partner-owned transitions (e.g., `delivered` from `placed`) return `409 invalid_status_transition` with `details.reason: "out_of_sequence"`.

## POST /v1/orders/\{id}/sandbox-status

Use this sandbox-only endpoint when you need to simulate LMN-driven lifecycle changes and test webhook delivery. It is available only on sandbox hosts with sandbox API keys.

Unlike `POST /v1/orders/{id}/status`, this endpoint enqueues webhook events:

| Change           | Webhook event          |
| ---------------- | ---------------------- |
| `status` changed | `order.status_changed` |

### Sandbox lifecycle statuses

```text theme={null}
placed ─┬─→ acquiring → secured → export_processing → in_transit → customs → delivered
        │      └─→ failed                                (acquiring only)
        ├─→ secondary_inspection_in_progress → secondary_inspection_ready ─┬─→ acquiring
        │                                              └─→ cancelled (secondary_inspection_declined / secondary_inspection_failed)
        └─→ cancelled                                  (from placed)
```

Inspection is **optional**: `placed → acquiring` directly is valid (skip
inspection); `placed → secondary_inspection_in_progress → secondary_inspection_ready → acquiring` is the inspected
path. Inspection failure resolves to `cancelled` (`secondary_inspection_failed`), never
`failed`.

| Status                             | Terminal | Typical meaning                                                                                                                                                                                                                       |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `placed`                           | no       | Order created and waiting for LMN bidding.                                                                                                                                                                                            |
| `secondary_inspection_in_progress` | no       | Optional pre-acquisition inspection underway. On complete → `secondary_inspection_ready`.                                                                                                                                             |
| `secondary_inspection_ready`       | no       | Inspection completed. Partner may confirm (`POST /v1/orders/{id}/confirm`) or decline (`DELETE`, reason `secondary_inspection_declined`); LMN/admin may also advance to `acquiring` or cancel (reason `secondary_inspection_failed`). |
| `acquiring`                        | no       | LMN is bidding or acquiring the vehicle.                                                                                                                                                                                              |
| `secured`                          | no       | LMN won or purchased the vehicle.                                                                                                                                                                                                     |
| `export_processing`                | no       | Korean export workflow in progress.                                                                                                                                                                                                   |
| `in_transit`                       | no       | Bill of Lading issued; vessel has departed Korea.                                                                                                                                                                                     |
| `customs`                          | no       | Vessel arrived at destination port; in customs-bonded area.                                                                                                                                                                           |
| `delivered`                        | yes      | Partner confirmed final delivery.                                                                                                                                                                                                     |
| `failed`                           | yes      | LMN could not acquire the vehicle.                                                                                                                                                                                                    |
| `cancelled`                        | yes      | Partner cancelled before LMN started acquisition, or LMN auto-cancelled for upstream reasons.                                                                                                                                         |

```bash theme={null}
curl -X POST \
  -H "x-api-key: $SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "secured",
    "purchase_price_usd": 20100,
    "auction_fee_usd": 440,
    "occurred_at": "2026-05-20T10:00:00+09:00"
  }' \
  https://sandbox-api.lmnauto.com/v1/orders/01HXYZ.../sandbox-status
```

| Field                      | Type               | Required | Description                                                                                                                                                                                                                            |
| -------------------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`                   | enum               | yes      | One of `placed`, `secondary_inspection_in_progress`, `secondary_inspection_ready`, `acquiring`, `secured`, `export_processing`, `in_transit`, `customs`, `delivered`, `failed`, `cancelled`.                                           |
| `purchase_price_usd`       | integer            | no       | Useful when simulating `secured`.                                                                                                                                                                                                      |
| `auction_fee_usd`          | integer \| null    | no       | Useful when simulating `secured`.                                                                                                                                                                                                      |
| `failure_reason`           | enum \| null       | no       | Only valid with `status: failed`.                                                                                                                                                                                                      |
| `cancellation_reason`      | string \| null     | no       | Only valid with `status: cancelled`.                                                                                                                                                                                                   |
| `secondary_inspection_url` | string (https URL) | no       | Only valid with `status: secondary_inspection_ready`. Simulates the LMN inspection-report link (v1.49) — it lands on `order.secondary_inspection_url` and in the emitted `order.status_changed` payload, matching production behavior. |
| `occurred_at`              | ISO 8601           | no       | Event timestamp. Defaults to server time.                                                                                                                                                                                              |

### QA cases

| Case                           | Request                                                        | Expected                                                                     |
| ------------------------------ | -------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Simulate acquisition           | `POST /sandbox-status` with `status: secured`                  | `200`, `order.status = secured`, `webhook_enqueued = true`                   |
| Simulate Korean export         | `POST /sandbox-status` with `status: export_processing`        | `200`, `order.status = export_processing`, `webhook_enqueued = true`         |
| Simulate vessel departure      | `POST /sandbox-status` with `status: in_transit`               | `200`, `order.status = in_transit`, `webhook_enqueued = true`                |
| Wrong endpoint guardrail       | `POST /status` with `status: in_transit`                       | `403 invalid_status_transition` (`details.reason: "partner_not_authorized"`) |
| Partner-owned destination push | `POST /status` with `status: customs` on an `in_transit` order | `200`, `status = customs`                                                    |
| Final delivery                 | `POST /status` with `status: delivered` on a `customs` order   | `200`, `status = delivered`                                                  |
| Out-of-sequence                | `POST /status` with `status: delivered` on a `placed` order    | `409 invalid_status_transition` (`details.reason: "out_of_sequence"`)        |

### Response

```json theme={null}
{
  "order": {
    "id": "01HXYZ...",
    "status": "secured",
    "amounts": {
      "purchase_price_usd": 20100,
      "auction_fee_usd": 440
    }
  },
  "webhook_enqueued": true,
  "allowed_statuses": ["placed", "secondary_inspection_in_progress", "secondary_inspection_ready", "acquiring", "secured", "export_processing", "in_transit", "customs", "delivered", "failed", "cancelled"]
}
```

Use `GET /v1/orders/{id}/events` after simulation to inspect delivery status, attempts, response codes, and payloads.

### Errors

| Code                        | HTTP | Condition                                                                                                                                                                                                        |
| --------------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `validation_error`          | 400  | Bad `status` enum or legacy `fulfillment_detail` field present.                                                                                                                                                  |
| `invalid_status_transition` | 403  | Partner attempted an LMN-owned status (`secondary_inspection_in_progress`, `secondary_inspection_ready`, `acquiring`, `secured`, `export_processing`, `in_transit`). `details.reason: "partner_not_authorized"`. |
| `invalid_status_transition` | 409  | Wrong sequence (e.g., `delivered` from non-`customs`). `details.reason: "out_of_sequence"`, `details.current_status` shows actual state.                                                                         |
| `order_not_found`           | 404  | Unknown order or wrong key.                                                                                                                                                                                      |

### SLA expectation

If a `customs` order doesn't receive a `delivered` push within 90 days, LMN's ops sends a daily digest reminder + email to the partner contact. Document your handoff process to make sure the push happens.
