1. Containers
  2. Write Containers

Containers

Write Containers

As a shipping provider, you can create a new container or update an existing one. Containers are used to group and track multiple deliveries / shipments together through their delivery journey.

WARNING

A container is limited to 100 status changes. They are intended to be used for a single trip and typically range between 10 - 25 tracking updates.

Create Container

POST
`/v1/containers`

You can create a container with no request body, but ideally you would provide an array for delivery / shipment IDs that you wanted to include in the container. You can, however, always add those deliveries / shipments later.

Request Body Parameters

add string[]
Array of shipment IDs to add to the container. This parameter is optional.

remove string[]
Array of shipment IDs to remove from the container. This parameter is optional.

status string
Current status of the container. If not provided, defaults to created for new containers.

metadata object
Custom key-value pairs for additional container data. This parameter is optional.

location_id string
ID of the hub location where this container is assigned. This parameter is optional.

layout_id string
ID of the storage layout for this container. Requires a valid location_id.

coordinates [number, number]
Latitude and longitude coordinates of the container.

tracking_update object
Detailed tracking information:

Show Details
status string
Current tracking status.
comment string
Additional notes about the update.
location_id string
Location identifier for this update.
layout_id string
Layout identifier for this update.
vehicle_id string
Associated vehicle identifier.
address object OR string
Address details for this update.
images string[]
Array of image URLs for proof of delivery.
image string
Single image URL.

user_id string
User identifier to associate with the container. Set to null to remove association.

estimated_delivery_at string<br Estimated delivery timestamp in ISO format or epoch seconds.

Validations

  1. Shipment Ownership:
    • All shipments must belong to the same organization as the API key.
    • Shipments cannot be already assigned to another container.
  2. Layout Assignment:
    • A layout_id cannot be assigned without a valid location_id.
    • The layout must belong to the specified location.

Usage Examples

  1. Create Empty Container
js
        fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  }
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Shipments
js
        const data = {
  add: ["ship_82A6o62SfaFeLRctFCMBrt"],
  location_id: "loc_abc123xyz",
  tracking_update: {
    status: "in_transit",
    comment: "Pickup completed"
  }
};

fetch("https://api.packagex.io/v1/containers", {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Location and Layout

Create a container with specific location, layout, and delivery estimate:

js
        const data = {
  location_id: "loc_warehouse_main",
  layout_id: "lay_zone_a_shelf_1",
  estimated_delivery_at: "2025-03-01T14:00:00Z",
  tracking_update: {
    status: "in_warehouse",
    comment: "Stored in Zone A, Shelf 1"
  }
};

fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Image

Create a container with images and location coordinates:

js
        const data = {
  coordinates: [40.7128, -74.0060],
  tracking_update: {
    status: "delivered",
    comment: "Delivered to main reception",
    images: [
      "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
      "data:image/jpeg;base64,/8K/5AAQSkZJRg..."
    ]
  }
};

fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Custom Metadata

Create a container with custom metadata and user assignment:

js
        const data = {
  user_id: "user_45D8r84UhcHfNTeuHEODpv",
  metadata: {
    route_number: "RT-123",
    vehicle_type: "van",
    priority_level: "high",
    special_instructions: "Handle with care",
    customer_reference: "PO-456789"
  },
  tracking_update: {
    status: "assigned",
    comment: "Assigned to express delivery route"
  }
};

fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Address Object

Create a container with detailed address information:

js
        const data = {
  tracking_update: {
    status: "in_transit",
    address: {
      line1: "123 Shipping Ave",
      line2: "Suite 456",
      city: "Logistics City",
      state: "LC",
      postal_code: "12345",
      country: "US"
    },
    comment: "Package collected from origin address"
  }
};

fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Address ID
js
        const data = {
  tracking_update: {
    status: "in_transit",
    address: "addr_abc123xyz",
    comment: "Package collected from origin address"
  }
};

fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      
  1. Create Container with Location ID
js
        const data = {
  tracking_update: {
    status: "in_transit",
    address: "loc_abc123xyz",
    comment: "Package collected from origin address"
  }
};

fetch(`https://api.packagex.io/v1/containers`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
}).then((res) => res.json());

const container = res.data;

      

Error Handling

  1. When attempting to add shipments that are already assigned to another container, the API returns:
js
        {
  "error": {
    "message": "Shipments ship_123, ship_456 are already part of another container",
    "code": "container.shipment_already_in_container",
    "status": 400
  }
}

      
  1. When attempting to add shipments that belong to a different organization, the API returns:
js
        {
  "error": {
    "message": "You are not the shipping provider for shipments ship_123, ship_456.",
    "code": "container.shipment_not_owned_by_org",
    "status": 400
  }
}

      
  1. When attempting to assign a layout without specifying a location, the API returns:
js
        {
  "error": {
    "message": "Cannot update layout without a location ID",
    "code": "invalid:layout",
    "status": 400,
    "errors": ["layout_id"]
  }
}

      
  1. When the system encounters issues processing uploaded images, it returns:
js
        {
  "error": {
    "message": "Could not convert image",
    "code": "scan.image",
    "status": 500
  }
}