# External Identifiers Guide

ShipStation API v2 uses external identifiers to link shipments and labels to records in your own system. Understanding how these identifiers work is crucial for integration.

## external_shipment_id

The `external_shipment_id` is **your system's unique identifier** for a shipment. This field serves the same purpose as `orderKey` in the v1 API.

### Key Characteristics

- **User-defined**: You set this value when creating a shipment
- **Optional but recommended**: Not required, but strongly recommended for tracking
- **Must be unique**: Each `external_shipment_id` must be unique per account
- **Immutable**: Cannot be changed after shipment creation
- **Exists at two levels**: Both shipments and labels have this field


### v1 to v2 Mapping

| **v1 Property** | **v2 Property** | **Notes** |
|  --- | --- | --- |
| orderKey | external_shipment_id | Same concept, different name |


**Example:**


```json
{
  "external_shipment_id": "ORDER-2024-12345",
  "ship_to": { ... },
  "ship_from": { ... }
}
```

### Automatic Population

If you **do not provide** an `external_shipment_id` when creating a shipment, the API will automatically generate one based on the `shipment_id`:

- Provided: `"external_shipment_id": "MY-ORDER-123"` → Uses your value
- Not provided: System generates → `"external_shipment_id": "se-123456789"`


Best Practice
Always provide your own `external_shipment_id` when creating shipments. This makes it much easier to correlate ShipStation records with your own system's orders.

## external_order_id

The `external_order_id` is a **read/write field** that represents the ID of an order record in the ShipStation UI system (if one exists).

### Key Characteristics

- **System-populated by default**: When a shipment is created through certain flows, ShipStation may automatically populate this
- **Now user-settable**: As of recent updates, you can set this value when creating shipments
- **Optional**: Not required for API-only workflows
- **Different from external_shipment_id**: These are two separate concepts


### What Sets external_order_id?

The `external_order_id` can be populated in several ways:

1. **Automatically** - When a shipment is imported from a connected sales channel (e.g., Shopify, Amazon)
2. **By the system** - When using legacy ShipStation UI v2 features
3. **By you** - You can now explicitly set this value when creating shipments via API


### When Do You Need It?

Most API-only integrations **do not need** to use `external_order_id`. Use it when:

- You're integrating with the ShipStation UI and need to link API-created shipments to UI orders
- You're migrating from legacy systems that used this field
- You need to track which ShipStation UI order a shipment originated from


**Example:**


```json
{
  "external_shipment_id": "MY-ORDER-123",
  "external_order_id": "SS-ORDER-456",
  "ship_to": { ... }
}
```

API-Only Workflows
If you're building a pure API integration (no ShipStation UI involvement), you typically only need `external_shipment_id`. The `external_order_id` is primarily useful for UI integrations.

## Shipment-Level vs Label-Level external_shipment_id

Both **shipments** and **labels** have an `external_shipment_id` field, and they're closely related:

### How They're Connected

1. **When you create a shipment**, you provide `external_shipment_id`
2. **When you create a label from that shipment**, the label inherits the shipment's `external_shipment_id`
3. **Both records share the same value**, making it easy to link labels back to your original order


**Example Flow:**


```
1. Create Shipment
   POST /v2/shipments
   {
     "external_shipment_id": "ORDER-2024-12345",
     ...
   }
   Response: { "shipment_id": "se-123456" }

2. Create Label from Shipment
   POST /v2/labels/shipment/se-123456
   
   Label Response includes:
   {
     "label_id": "se-789012",
     "shipment_id": "se-123456",
     "external_shipment_id": "ORDER-2024-12345"  ← Inherited from shipment
   }
```

### Querying by external_shipment_id

You can retrieve records using `external_shipment_id`:


```http
GET /v2/labels/external_shipment_id/ORDER-2024-12345
GET /v2/shipments/external_shipment_id/ORDER-2024-12345
```

This makes it easy to find ShipStation records using your own system's identifiers.

## Best Practices

### Always Use Your Own IDs


```json
// ✅ Good - Provide your own external_shipment_id
{
  "external_shipment_id": "SHOPIFY-ORDER-98765",
  "ship_to": { ... }
}

// ❌ Not ideal - Relying on auto-generated IDs
{
  // No external_shipment_id provided
  // System will use "se-123456789"
  "ship_to": { ... }
}
```

### Use Consistent Naming

Choose a naming pattern and stick with it:

- `ORDER-{id}` (e.g., `ORDER-12345`)
- `{source}-{id}` (e.g., `SHOPIFY-98765`)
- `{prefix}-{date}-{id}` (e.g., `WEB-20240615-001`)


### Don't Confuse the Two


```json
{
  "external_shipment_id": "MY-ORDER-123",    // Your order ID
  "external_order_id": "SS-UI-ORDER-456",    // ShipStation UI order ID (if applicable)
  "shipment_id": "se-789012"                  // ShipStation's internal ID (read-only)
}
```

## Related Guides

- **[Understanding Orders & Shipments](/orders/understanding-orders-shipments)** - Core concepts overview
- **[Shipment Numbers & Uniqueness](/orders/shipment-numbers)** - Learn about `shipment_number`
- **[Legacy API Migration](/orders/legacy-migration)** - Migrating from v1 `orderKey`