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

# Core Concepts

> Key concepts and mental model for the Flex Forward API

# Core concepts

This page explains the key concepts behind the Flex Forward API — how resources relate to each other, how labels progress through their lifecycle, and how tracking data is normalized across couriers.

## Resources

The API manages three related resources, all linked by the **label ID** (a UUID):

| Resource       | Endpoint             | Description                                        |
| -------------- | -------------------- | -------------------------------------------------- |
| Label          | `POST /labels`       | A shipping label request submitted to a courier    |
| Label Document | `GET /labels/{id}`   | The printable airway bill (PDF or PNG) for a label |
| Tracking       | `GET /tracking/{id}` | Real-time shipment tracking data for a label       |

The label ID returned from `POST /labels` is the primary key used across all operations. There is no separate tracking ID — tracking is always accessed by label ID.

## Label lifecycle

A label progresses through the following states:

```mermaid theme={null}
stateDiagram-v2
    [*] --> Created : Courier accepts
    [*] --> Failed : Courier rejects
    Created --> DocumentAvailable : Label document ready
    DocumentAvailable --> TrackingActive : Courier scans package
    TrackingActive --> Delivered : Shipment delivered
    TrackingActive --> Exception : Issue during transit
```

<Steps>
  <Step title="Created">
    The label request was accepted by the courier. The response includes `courierOrderNumber`, `courierTrackingNumber`, and the label `id`. The label document is available for retrieval.
  </Step>

  <Step title="Document available">
    The airway bill PDF or PNG can be downloaded via `GET /labels/{id}`. Print and attach it to the shipment. The document URL is permanent and does not expire. Supported formats are PDF and PNG.
  </Step>

  <Step title="Tracking active">
    Once the courier scans the package, tracking data becomes available via `GET /tracking/{id}`. Tracking data is fetched from the courier in near-real-time. The tracking status progresses through stages like `InfoReceived`, `InTransit`, and `Delivered`. Normalized status tags may evolve as additional courier data becomes available.
  </Step>
</Steps>

If the courier rejects the request, the label is persisted with `status: failed` and includes the courier error details. See [Error Handling](/error-handling#downstream-courier-errors-502) for details.

## Tracking status model

Tracking data uses a unified status model inspired by industry standards. Each tracking response includes a top-level `tag` and `subtag`, plus an array of `checkpoints` representing individual tracking events.

### Status tags

| Tag            | Meaning                                                                        |
| -------------- | ------------------------------------------------------------------------------ |
| `Pending`      | Label created but not yet received by the courier                              |
| `InfoReceived` | Courier has received shipment information                                      |
| `InTransit`    | Shipment is in transit                                                         |
| `Delivered`    | Shipment has been delivered                                                    |
| `Exception`    | An issue occurred during transit (e.g., failed delivery attempt, customs hold) |
| `Cancelled`    | Shipment has been cancelled                                                    |
| `Unknown`      | Status could not be determined                                                 |

The `subtag` field provides finer granularity (e.g., `InTransit_001`, `Exception_002`). Use the `tag` for high-level status logic and the `subtag` for detailed status display.

### Checkpoints

Each checkpoint represents a single tracking event:

```json theme={null}
{
  "checkpointTime": "2026-03-15T14:30:00Z",
  "city": "Tokyo",
  "state": "Tokyo",
  "countryRegion": "JP",
  "location": null,
  "message": "Departed from sorting facility",
  "tag": "InTransit",
  "subtag": "InTransit_001",
  "subtagMessage": "In transit",
  "slug": "yunexpress"
}
```

Checkpoints are ordered with the most recent event first (reverse chronological). The earliest event appears last in the array.

## Carrier normalization

Each courier has its own API format, status codes, and error conventions. Flex Forward normalizes these differences:

* **One request format** — submit the same JSON structure regardless of courier. Courier-specific details are handled internally.
* **One response format** — receive a consistent label response with `id`, `status`, `courierOrderNumber`, `courierTrackingNumber`, and (if failed) `error`.
* **Unified tracking** — tracking events from different couriers are mapped to the same status tag taxonomy and checkpoint format.

This means your integration code does not need to handle courier-specific logic. As new couriers are enabled, your existing integration works without changes.

## Couriers and product codes

Each label request requires a `courier` code and a `productCode`. Call [`GET /couriers`](/api-reference/couriers/list-couriers) to list the valid courier codes available to your account, then pass one of the returned `code` values as `courier` when creating a label.

| Courier    | Slug         | Product Code | Description                      |
| ---------- | ------------ | ------------ | -------------------------------- |
| YunExpress | `yunexpress` | `HKMUZXR`    | Standard cross-border e-commerce |

After selecting a courier, call [`GET /products`](/api-reference/products/list-products) with that courier code to list product codes available for your shipping lanes. The `serviceCode` field is optional and enables specific service levels when available.

## Address reference data

Address fields require standardized codes:

* **`countryCode`** — ISO 3166-1 alpha-2 country code (e.g., `US`, `JP`, `CN`, `GB`, `DE`)
* **`state`** — State or province code, required for countries with state-level addressing (e.g., `CA`, `NY`, `TX` for the United States)

<Note>
  For a complete list of US state codes, see the [State Reference](https://apidocs.returnhelper.com/reference/supported-states).
</Note>

## Integration flow

The typical integration sequence:

```
1. Authenticate     →  Include Bearer token in all requests
2. Create label     →  POST /labels  →  receive label ID + courier tracking number
3. Retrieve document →  GET /labels/{id}  →  download PDF/PNG
4. Track shipment   →  GET /tracking/{id}  →  poll for status updates
```

All three GET operations use the same label `id` returned from the initial `POST /labels` call. There is no need to manage separate identifiers for documents and tracking.

<Note>
  Tracking data is fetched from the courier in real time. For shipments that have not yet been scanned by the courier, the tracking response may return a `Pending` or `InfoReceived` status with no checkpoints.
</Note>
