Skip to content
Last updated

Shipment Numbers & Uniqueness

The shipment_number is a user-friendly, human-readable identifier for shipments. Understanding how it works and its relationship to external_shipment_id is important for proper integration.

What is shipment_number?

The shipment_number is equivalent to orderNumber in the v1 API and ShipStation UI. It's designed to be:

  • Human-readable: Easy to reference in conversations and support tickets
  • Unique per account: No two shipments can have the same shipment_number
  • Optional: You can provide your own or let the system generate one
  • Mutable: Can be updated after creation (unlike external_shipment_id)

v1 to v2 Mapping

v1 / UI Termv2 TermPurpose
orderNumbershipment_numberUser-friendly display number

Uniqueness Rules

Enforced Uniqueness

The shipment_number field has strict uniqueness enforcement at the account level:

  • ✅ Each shipment_number must be unique within your ShipStation account
  • ❌ Attempting to create a shipment with a duplicate shipment_number will fail
  • ⚠️ This applies across all shipments, regardless of status

Example Error:

{
  "errors": [
    {
      "message": "A shipment with shipment_number 'ORDER-12345' already exists",
      "field": "shipment_number"
    }
  ]
}

How external_shipment_id Differs

FieldUniquenessMutabilityAuto-Generated
shipment_numberRequired uniqueCan be updatedYes (if not provided)
external_shipment_idRequired uniqueCannot be changedYes (if not provided)

Both fields must be unique, but shipment_number can be updated after creation while external_shipment_id is immutable.

Automatic Population Rules

ShipStation follows a duplication rule when neither field is provided:

Scenario 1: You Provide Both

{
  "external_shipment_id": "ORDER-2024-12345",
  "shipment_number": "ORD-12345",
  ...
}

Result: Both values are used as provided.

Scenario 2: You Provide Only external_shipment_id

{
  "external_shipment_id": "ORDER-2024-12345",
  // shipment_number not provided
  ...
}

Result:

  • external_shipment_id = "ORDER-2024-12345" (your value)
  • shipment_number = "ORDER-2024-12345" (duplicated from external_shipment_id)
Common Pattern

Many integrations only provide external_shipment_id and let the system duplicate it to shipment_number. This works well if your external IDs are already human-readable.

Scenario 3: You Provide Only shipment_number

{
  // external_shipment_id not provided
  "shipment_number": "ORD-12345",
  ...
}

Result:

  • shipment_number = "ORD-12345" (your value)
  • external_shipment_id = "se-123456789" (system-generated based on shipment_id)

Scenario 4: You Provide Neither

{
  // Neither field provided
  ...
}

Result: Both are auto-generated based on the internal shipment_id:

  • external_shipment_id = "se-123456789"
  • shipment_number = "se-123456789"
Not Recommended

Relying on auto-generated values makes it harder to correlate ShipStation records with your own system. Always provide at least external_shipment_id.

Best Practices

Use Meaningful Identifiers

// ✅ Good - Clear, readable identifiers
{
  "external_shipment_id": "SHOPIFY-ORDER-98765",
  "shipment_number": "WEB-2024-0615-001"
}

// ❌ Not ideal - Cryptic or auto-generated values
{
  "external_shipment_id": "se-123456789",
  "shipment_number": "se-123456789"
}

Handle Uniqueness Conflicts

If you encounter a duplicate shipment_number error:

  1. Check if the shipment already exists - Query by external_shipment_id to see if you already created it
  2. Use a different number - Append a suffix or increment a counter
  3. Update the existing shipment - If you're re-creating a canceled shipment
// Example: Retry with incremented number
try {
  await createShipment({
    external_shipment_id: "ORDER-12345",
    shipment_number: "ORD-12345"
  });
} catch (error) {
  if (error.field === 'shipment_number') {
    // Retry with suffixed number
    await createShipment({
      external_shipment_id: "ORDER-12345",
      shipment_number: "ORD-12345-RETRY"
    });
  }
}

Leverage the Duplication Rule

If your external_shipment_id values are already user-friendly, just provide that:

{
  "external_shipment_id": "ORDER-2024-06-15-001"
  // shipment_number will automatically duplicate: "ORDER-2024-06-15-001"
}

This reduces redundancy and ensures consistency.

Updating shipment_number

Unlike external_shipment_id, you can update the shipment_number after creation:

PUT /v2/shipments/se-123456
{
  "shipment_number": "NEW-NUMBER-456"
}
Must Still Be Unique

The new shipment_number must still be unique across your account. If another shipment already has that number, the update will fail.

Common Scenarios

E-commerce Integration

{
  "external_shipment_id": "SHOPIFY-98765",
  "shipment_number": "ORDER-2024-001",
  // external_shipment_id tracks the Shopify order
  // shipment_number is what customers see
}

Sequential Order Numbers

{
  "external_shipment_id": "UUID-a1b2c3d4",
  "shipment_number": "100001",  // Sequential counter
}

Date-Based Order Numbers

{
  "external_shipment_id": "INTERNAL-789",
  "shipment_number": "20240615-001",  // YYYYMMDD-sequence
}