> ## 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.

# Quickstart

> Go from zero to your first shipping label in minutes

# Quickstart

This guide walks you through creating your first shipping label, retrieving the label document, and tracking the shipment.

## Prerequisites

* An API token (see [Authentication](/authentication) for how to obtain one)
* `curl` or any HTTP client
* The development base URL: `https://sandbox.flexforward.com`

<Note>
  Use the development environment for testing. It connects to courier sandbox services and does not create live shipments.
</Note>

## Step 1: Authenticate

Include your Bearer token in the `Authorization` header of every request:

```
Authorization: Bearer YOUR_API_TOKEN
```

See the [Authentication](/authentication) page for token best practices and error responses.

## Step 2: Create a label

Send a `POST /labels` request with your shipment details. The `idempotencyKey` ensures that retrying the same request does not create a duplicate label.

<Note>
  **Minimum required fields:** `idempotencyKey`, `courier`, `service.productCode`, `shipment.shipTo` (contact with `firstName`, address with `countryCode`, `city`, `postalCode`, `streetLines`), and at least one parcel with `weight` and one item (`descriptionEn`, `quantity`, `unitPrice`, `unitWeight`). The `shipment.shipFrom` field is required for certain couriers and shipping lanes — confirm requirements with the Flex Forward team during onboarding.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://sandbox.flexforward.com/labels \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "idempotencyKey": "quickstart-test-001",
      "courier": "yunexpress",
      "service": {
        "productCode": "HKMUZXR"
      },
      "shipment": {
        "shipFrom": {
          "contact": {
            "firstName": "Test",
            "lastName": "Sender",
            "phone": "+81-90-1234-5678"
          },
          "address": {
            "countryCode": "JP",
            "city": "Tokyo",
            "postalCode": "100-0001",
            "streetLines": ["1-1 Marunouchi"]
          }
        },
        "shipTo": {
          "contact": {
            "firstName": "Test",
            "lastName": "Recipient",
            "phone": "+1-555-0100"
          },
          "address": {
            "countryCode": "US",
            "city": "Los Angeles",
            "state": "CA",
            "postalCode": "90001",
            "streetLines": ["123 Main St"]
          }
        },
        "parcels": [
          {
            "weight": 0.5,
            "items": [
              {
                "descriptionEn": "T-Shirt",
                "descriptionLocal": "Tシャツ",
                "quantity": 2,
                "unitPrice": { "amount": 25.00, "currency": "USD" },
                "unitWeight": 0.25
              }
            ]
          }
        ]
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://sandbox.flexforward.com/labels', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      idempotencyKey: 'quickstart-test-001',
      courier: 'yunexpress',
      service: {
        productCode: 'HKMUZXR'
      },
      shipment: {
        shipFrom: {
          contact: { firstName: 'Test', lastName: 'Sender', phone: '+81-90-1234-5678' },
          address: { countryCode: 'JP', city: 'Tokyo', postalCode: '100-0001', streetLines: ['1-1 Marunouchi'] }
        },
        shipTo: {
          contact: { firstName: 'Test', lastName: 'Recipient', phone: '+1-555-0100' },
          address: { countryCode: 'US', city: 'Los Angeles', state: 'CA', postalCode: '90001', streetLines: ['123 Main St'] }
        },
        parcels: [{
          weight: 0.5,
          items: [{
            descriptionEn: 'T-Shirt',
            descriptionLocal: 'Tシャツ',
            quantity: 2,
            unitPrice: { amount: 25.00, currency: 'USD' },
            unitWeight: 0.25
          }]
        }]
      }
    })
  });
  const label = await response.json();
  console.log(label.id); // Use this ID for document retrieval and tracking
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://sandbox.flexforward.com/labels',
      headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
      json={
          'idempotencyKey': 'quickstart-test-001',
          'courier': 'yunexpress',
          'service': {
              'productCode': 'HKMUZXR'
          },
          'shipment': {
              'shipFrom': {
                  'contact': {'firstName': 'Test', 'lastName': 'Sender', 'phone': '+81-90-1234-5678'},
                  'address': {'countryCode': 'JP', 'city': 'Tokyo', 'postalCode': '100-0001', 'streetLines': ['1-1 Marunouchi']}
              },
              'shipTo': {
                  'contact': {'firstName': 'Test', 'lastName': 'Recipient', 'phone': '+1-555-0100'},
                  'address': {'countryCode': 'US', 'city': 'Los Angeles', 'state': 'CA', 'postalCode': '90001', 'streetLines': ['123 Main St']}
              },
              'parcels': [{
                  'weight': 0.5,
                  'items': [{
                      'descriptionEn': 'T-Shirt',
                      'descriptionLocal': 'Tシャツ',
                      'quantity': 2,
                      'unitPrice': {'amount': 25.00, 'currency': 'USD'},
                      'unitWeight': 0.25
                  }]
              }]
          }
      }
  )
  label = response.json()
  print(label['id'])  # Use this ID for document retrieval and tracking
  ```
</CodeGroup>

A successful response returns HTTP 201 with the label details:

```json 201 Created theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "created",
  "courier": "yunexpress",
  "courierOrderNumber": "YT2503010001",
  "courierTrackingNumber": "YT2503010001CN",
  "error": null
}
```

Key fields in the response:

| Field                   | Description                                                         |
| ----------------------- | ------------------------------------------------------------------- |
| `id`                    | The label UUID. Use this to retrieve documents and tracking.        |
| `status`                | `created` on success, `failed` if the courier rejected the request. |
| `courierOrderNumber`    | The order number assigned by the courier.                           |
| `courierTrackingNumber` | The tracking number assigned by the courier.                        |
| `error`                 | `null` on success. Contains `code` and `message` on failure.        |

<Warning>
  If you retry the same request with the same `idempotencyKey`, the API returns HTTP 200 with the original result instead of creating a duplicate label. See [Idempotency and Retries](/idempotency-and-retries) for details.
</Warning>

## Step 3: Retrieve the label document

Use the label `id` from the previous response to retrieve the airway bill document:

```bash theme={null}
curl https://sandbox.flexforward.com/labels/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

```json 200 OK theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "customerOrderNumber": "quickstart-test-001",
  "url": "https://label-documents.example.com/labels/a1b2c3d4.pdf",
  "labelFormat": "pdf"
}
```

Download the PDF or PNG from the returned `url` to print the shipping label.

## Step 4: Track the shipment

Use the same label `id` to retrieve tracking information:

```bash theme={null}
curl https://sandbox.flexforward.com/tracking/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

```json 200 OK theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "trackingNumber": "YT2503010001CN",
  "tag": "InfoReceived",
  "subtag": "InfoReceived_001",
  "subtagMessage": "Shipment information received",
  "slug": "yunexpress",
  "checkpoints": [
    {
      "checkpointTime": "2026-03-15T10:30:00Z",
      "city": "Tokyo",
      "state": "Tokyo",
      "countryRegion": "JP",
      "location": null,
      "message": "Shipment information received",
      "tag": "InfoReceived",
      "subtag": "InfoReceived_001",
      "subtagMessage": "Shipment information received",
      "slug": "yunexpress"
    }
  ]
}
```

The `tag` field provides the high-level shipment status. See [Core Concepts](/core-concepts#tracking-status-model) for the full list of tracking statuses.

## What success looks like

After completing this quickstart, verify you can:

* [ ] Authenticate successfully with your Bearer token
* [ ] Create a test label in the development environment
* [ ] Retrieve a printable label document (PDF or PNG)
* [ ] Fetch normalized tracking updates for your test label

## What's next

<CardGroup cols={3}>
  <Card title="Error Handling" icon="triangle-exclamation" href="/error-handling">
    Understand error responses and how to troubleshoot common issues.
  </Card>

  <Card title="Idempotency and Retries" icon="rotate" href="/idempotency-and-retries">
    Learn how to retry requests safely without creating duplicate labels.
  </Card>

  <Card title="Core Concepts" icon="book" href="/core-concepts">
    Understand the label lifecycle, tracking model, and carrier normalization.
  </Card>
</CardGroup>
