NAV Navbar
shell ruby python php csharp
cURL ruby python php csharp

Introduction

Welcome to the Vanlo API! You can use our API to verify addresses, rate and create shipments and shipping labels, and monitor tracking codes.

This is an EasyPost-compatible API, so switching from EasyPost to Vanlo is as simple as changing your request URL and API key!

We have client libraries / SDKs for Ruby, Python, PHP and C#. You can view code examples on the right, and you can switch the programming language of the examples with the tabs in the top right.

Request URL

Test: https://test.vanlo.com/api/v1/...

Production: https://www.vanlo.com/api/v1/...

Authentication

Authentication is performed by including your API key with every request (cURL), or by setting it globally in one of our client libraries / SDKs:

curl -X METHOD https://www.vanlo.com/api/v1/... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'

Vanlo.api_key = 'VANLO_API_KEY'
import vanlo

vanlo.api_key = 'VANLO_API_KEY'
require_once("/path/to/lib/vanlo.php");

\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');
using Vanlo;

ClientManager.SetCurrent("VANLO_API_KEY");

Make sure to replace VANLO_API_KEY with your API key.

Vanlo uses API keys for authentication and identification.

Vanlo expects for the API key to be included in all API requests as an authorization bearer token:

Authorization: Bearer VANLO_API_KEY

Test Environment

In the client libraries / SDKs you can access the test environment by setting the API base value before performing any actions:

curl -X METHOD https://test.vanlo.com/api/v1/... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'

Vanlo.api_key = 'VANLO_API_KEY'
Vanlo.api_base = 'https://test.vanlo.com/api/v1'
import vanlo

vanlo.api_key = 'VANLO_API_KEY'
vanlo.api_base = 'https://test.vanlo.com/api/v1'
require_once("/path/to/lib/vanlo.php");

\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');
\Vanlo\Vanlo::setApiBase('https://test.vanlo.com/api/v1');
using Vanlo;

ClientManager.SetCurrent("VANLO_API_KEY", "https://test.vanlo.com/api/v1");

Vanlo offers a test environment which you can develop against without incurring any real charges or generating any live postage labels or tracking codes.

You can find your test API Key by logging in to the Vanlo Dashboard, entering "test mode" by clicking the toggle in the bottom of the left side bar, and then visiting the API Keys page: https://dashboard.vanlo.com/apikey

Shipments

Shipment Object

A purchased Shipment:

{
  "id": "shp_...",
  "object": "Shipment",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "reference": "order-1042",
  "usps_zone": "08",
  "custom_id": "order-1042",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "return_address": null,
  "buyer_address": null,
  "parcel": {
    "id": "prcl_...",
    "object": "Parcel",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "predefined_package": null,
    "weight": 32.0
  },
  "customs_info": null,
  "rates": [
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "GroundAdvantage",
      "delivery_date": "2026-10-26",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 6,
      "rate": "9.84",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DUXX0XXXXC08020",
        "quoted_service": "GroundAdvantage",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "12.47",
        "discount": "2.63",
        "discount_date": "2026-09-29",
        "total_freight": "9.84",
        "total_surcharges": "0.00",
        "services": {
          "DUXX0XXXXC08020": 12.47
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Priority",
      "delivery_date": "2026-10-23",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 3,
      "rate": "11.20",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DPXX0XXXXC08020",
        "quoted_service": "Priority",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "14.95",
        "discount": "3.75",
        "discount_date": "2026-09-29",
        "total_freight": "11.20",
        "total_surcharges": "0.00",
        "services": {
          "DPXX0XXXXC08020": 14.95
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Express",
      "delivery_date": "2026-10-22",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 2,
      "rate": "48.75",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DEXX0XXXXC08020",
        "quoted_service": "Express",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "52.30",
        "discount": "3.55",
        "discount_date": "2026-09-29",
        "total_freight": "48.75",
        "total_surcharges": "0.00",
        "services": {
          "DEXX0XXXXC08020": 52.3
        },
        "rdc": "04"
      },
      "usps_cubic": false
    }
  ],
  "selected_rate": {
    "id": "rate_...",
    "object": "Rate",
    "carrier_account_id": "ca_...",
    "shipment_id": "shp_...",
    "created_at": "2026-10-20T15:04:12Z",
    "service": "Priority",
    "delivery_date": "2026-10-23",
    "delivery_datetime": null,
    "delivery_date_guaranteed": false,
    "delivery_days": 3,
    "rate": "11.20",
    "carrier": "USPS",
    "rate_detail": {
      "zone": "08",
      "sku": "DPXX0XXXXC08020",
      "quoted_service": "Priority",
      "billing_weight": "32.0 OZ",
      "non_cubic_weight": "32.0 OZ",
      "volume": 320.0,
      "usps_cubic": false,
      "commercial_freight": "14.95",
      "discount": "3.75",
      "discount_date": "2026-09-29",
      "total_freight": "11.20",
      "total_surcharges": "0.00",
      "services": {
        "DPXX0XXXXC08020": 14.95
      },
      "rdc": "04"
    },
    "usps_cubic": false
  },
  "tracker": {
    "id": "trk_...",
    "object": "Tracker",
    "shipment_id": "shp_...",
    "tracking_details": [],
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "status": "unknown",
    "carrier": "USPS",
    "tracking_code": "9405500106024190341287",
    "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
  },
  "postage_label": {
    "object": "PostageLabel",
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "id": "pl_...",
    "integrated_form": null,
    "label_date": "2026-10-20",
    "label_epl2_url": null,
    "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_resolution": null,
    "label_size": null,
    "label_type": null,
    "label_file_type": "application/pdf",
    "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_zpl_url": null
  },
  "refund_status": null,
  "tracking_code": "9405500106024190341287",
  "status": null,
  "insurance": null,
  "is_return": null,
  "options": {
    "delivery_confirmation": "SIGNATURE",
    "label_format": "pdf",
    "label_size": "4X6",
    "label_date": "2026-10-20",
    "print_custom": [
      {
        "name": "Order",
        "value": "1042"
      }
    ]
  }
}

A Shipment holds the addresses, parcel and customs details of one package. Creating it returns a rate for each available service, and buying one of those rates purchases the label and fills in selected_rate, postage_label, tracker and tracking_code.

Parameter Type Specification
id string Unique identifier, begins with "shp_"
object string "Shipment"
usps_zone string The USPS zone of the shipment. An integer such as 8 until the label is bought, then a string such as "08". Present only on USPS shipments
to_address Address The destination address
from_address Address The origin address
parcel Parcel The dimensions and weight of the package
customs_info CustomsInfo Information for the processing of customs
rates Rate[] All associated Rate objects
selected_rate Rate The specific rate purchased for the shipment, or null if unpurchased or purchased through another mechanism
tracker Tracker The associated Tracker object
postage_label PostageLabel The associated PostageLabel object
reference string Your reference for the shipment, as sent on create
custom_id string Your key for the shipment, as sent on create
refund_status string The current status of the shipment refund process. Possible values are "submitted", "refunded", "rejected"
refund_error string Why the refund was rejected, present only when it was
tracking_code string If purchased, the tracking code will appear here as well as within the Tracker object
status string The current tracking status of the shipment. Null until the carrier reports the first scan
is_return boolean Set true to create as a return
options Options The options sent with the shipment
insurance float The declared insurance amount, if insurance was bought with the insurance_amount option
return_address Address Optional return address, if different from the origin address
buyer_address Address Optional buyer address, if different from the destination address
usps_tracking_code string USPS tracking code, present when a non-USPS service hands the package to USPS for delivery
usps_tracker Tracker Tracker for usps_tracking_code, present with it
forms object[] The commercial invoice of an international FedEx label, as one { object: "Form", form_type: "commercial_invoice", form_url, submitted_electronically, created_at } entry. Present only when one was generated
created_at datetime When the shipment was created
updated_at datetime When the shipment was last updated

Carrier Services

The services each carrier returns on rates, and the options it accepts. Which services you are quoted depends on your account.

Services

Service Name What it is for
GroundAdvantage Ground Advantage Ground delivery for packages, the standard domestic choice.
First First Lightweight domestic mail, priced for small parcels.
Priority Priority Faster domestic delivery, in one to three days.
Express Express The fastest domestic option, in one to two days.
ParcelSelect Parcel Select Economy ground delivery for larger or high-volume shipments.
MediaMail Media Mail Discounted rate restricted to books and media contents.
LibraryMail Library Mail Discounted rate restricted to library materials.
FirstClassMailInternational First Class Mail International Lightweight international mail.
FirstClassPackageInternationalService First Class Package International Service Economy international delivery for small packages.
PriorityMailInternational Priority Mail International Faster international delivery for packages.
ExpressMailInternational Express Mail International The fastest international option.

Options only for USPS

Fees entries in rate_detail.services

USPS entries are 15-character USPS codes. The first is the postage, and each one below is an extra fee. Every code here ends in 0000.

Code Fee When it applies
DXSP0EXXXXX0000
DXSV0EXXXXX0000
DXSL0EXXXXX0000
DXSM0EXXXXX0000
Signature confirmation You asked for signature confirmation. The code differs by service: Priority Mail and Ground Advantage, then Parcel Select, Library Mail and Media Mail.
DXSP0EJXXXX0000
DXSV0EJXXXX0000
DXSL0EJXXXX0000
DXSM0EJXXXX0000
DXSF0EJPXXX0000
Signature confirmation, restricted delivery You asked for signature confirmation restricted to the named recipient.
DXAX0XXXXXX0000 Adult signature You asked for an adult signature.
DXBX0XXXXXX0000 Adult signature, restricted delivery You asked for an adult signature restricted to the named recipient.
DX1F0XXLXRX0000 Non-machinable letter A First-Class letter USPS cannot run through its letter equipment - the wrong length-to-width ratio, or too thin for its size.
D811XUXXXXX0000
D811XXXXXXX0000
Long parcel The longest side measures more than 22 inches.
D812XUXXXXX0000
D812XXXXXXX0000
Long parcel, over 30 inches The longest side measures more than 30 inches. The code differs by service: Ground Advantage, then every other service.
D813XUXXXXX0000
D813XXXXXXX0000
Oversized parcel The parcel measures more than 2 cubic feet. The code differs by service: Ground Advantage, then every other service.
DX0P0HXXXCX0000
DX0E0HXXXCX0000
DX0U0HXXXCX0000
DX0V0HXXXCX0000
Hazardous materials You declared hazardous contents. The code differs by service: Priority Mail, Priority Mail Express, Ground Advantage, then Parcel Select. It is charged on Priority Mail and Priority Mail Express, and free on Ground Advantage and Parcel Select.

Priority Mail Express carries no separate signature fee. That service already includes a signature, so no signature code appears on it. An adult signature is still charged.

The two length fees never both appear. A parcel over 30 inches is charged the over-30 fee instead of the over-22 one, not on top of it. An oversized parcel is separate and can appear alongside either.

Media Mail and Library Mail carry no length or oversized fee.

International shipments carry almost nothing. No signature, adult signature, length, oversized or non-machinable fee can appear on an international USPS shipment. Hazardous materials is the one exception.

USPS publishes the current price for each of these fees in Notice 123, the USPS price list.

Services

Service Name What it is for
FEDEX_GROUND Ground Ground delivery to businesses.
GROUND_HOME_DELIVERY Home Delivery Ground delivery to residential addresses.
FEDEX_2_DAY FedEx 2Day Delivery in two business days.
FEDEX_2_DAY_AM FedEx 2Day AM Delivery in two business days by the morning.
FEDEX_EXPRESS_SAVER ExpressSaver Express delivery in three business days.
STANDARD_OVERNIGHT FedEx Standard Overnight Next business day by the end of day.
PRIORITY_OVERNIGHT FedEx Priority Overnight Next business day by the morning.
FIRST_OVERNIGHT FedEx First Overnight Next business day, earliest available delivery.
INTERNATIONAL_ECONOMY FedEx Intl Economy Economy international delivery.
INTERNATIONAL_GROUND International Ground Ground delivery to Canada.
INTERNATIONAL_FIRST InternationalFirst The earliest international express delivery.
INTERNATIONAL_PRIORITY FedEx Intl Priority Fast international delivery.
SMART_POST SmartPost Economy delivery with final handoff to USPS.

Options only for FedEx

Services

Service Name What it is for
Ground Ground Ground delivery, the standard domestic choice.
3DaySelect 3 Day Select Delivery in three business days.
2ndDayAir 2nd Day Air Delivery in two business days.
2ndDayAirAM 2nd Day Air AM Delivery in two business days by the morning.
NextDayAirSaver Next Day Air Saver Next business day by the end of day.
NextDayAir Next Day Air Next business day by midday.
NextDayAirEarlyAM Next Day Air Early AM Next business day, earliest available delivery.
UPSStandard UPS Standard Ground delivery to Canada and Mexico.
UPSSaver UPS Saver International express by the end of day.
Express Express International express by the morning.
ExpressPlus Express Plus International express, earliest available delivery.
Expedited Expedited Economy international delivery.

Options only for UPS

Services

Service Name What it is for
UniUni UniUni Last-mile delivery, the single UniUni service.

Options only for UniUni

Services

Service Name What it is for
Parcel Parcel Economy parcel delivery.
GroundAdvantage Ground Advantage Ground delivery with final handoff to USPS.
Priority Priority Faster delivery with final handoff to USPS.
GlobalStandard Global Standard Economy international delivery.
GlobalPriority Global Priority Faster international delivery.
GlobalEPacket Global E Packet International delivery for lightweight packets.
GlobalParcel Global Parcel International delivery for parcels.

Options

Services

Service Name
ECOCE OneParcel Economy Central
ECOEA OneParcel Economy East
ECONE OneParcel Economy Northeast
ECONJ OneParcel Economy New Jersey
ECOSE OneParcel Economy Southeast
ECOSL OneParcel Economy Salt Lake City
ECOSO OneParcel Economy South
ECOWE OneParcel Economy West
STDCE OneParcel Standard Central
STDEA OneParcel Standard East
STDNE OneParcel Standard Northeast
STDNJ OneParcel Standard New Jersey
STDSE OneParcel Standard Southeast
STDSL OneParcel Standard Salt Lake City
STDSO OneParcel Standard South
STDWE OneParcel Standard West
EXPNJ OneParcel Expedited New Jersey
REGSL OneParcel Regional Salt Lake
BPMCE Bound Printed Matter Central
BPMNE Bound Printed Matter Northeast
BPMSO Bound Printed Matter South
BPMWE Bound Printed Matter West

Some OneParcel rates come from partner networks, so codes outside this list can appear.

Options

Services

Service Name What it is for
Drive DoorDash Drive Same-day local delivery by a driver, the single DoorDash service.

Options only for DoorDash

Services

Service Name What it is for
RD Routine Delivery Regional ground delivery, the standard OnTrac service.
SD Same Day Same-day regional delivery.

OnTrac quotes whatever services your contract carries; these are the two standard ones.

Options only for OnTrac

Services

Service Name
groundPlus Ground Plus
groundPlusOne Ground Plus 1
groundPlusTwo Ground Plus 2
groundPlusThree Ground Plus 3
groundPlusFour Ground Plus 4
nextDay Next Day
sameDay Same Day
twoDay Two Day
expressAir Express Air
premiumEconomy Premium Economy
vehoValue Veho Value

Services

Service Name
StandardDdu Standard DDU
StandardDduDelcon Standard DDU Delcon
PriorityDdu Priority DDU
PriorityDduDelcon Priority DDU Delcon
PriorityDdp Priority DDP
PriorityDdpDelcon Priority DDP Delcon
ExpeditedDdpDelcon Expedited DDP Delcon
ExpeditedDduDelcon Expedited DDU Delcon
ExpressDdp Express DDP
ExpressDdpDelcon Express DDP Delcon
ExpressDduDelcon Express DDU Delcon
epacketDdp ePacket DDP
GlobalPlus Global Plus

Services

Service Name
DHLParcelGround DHL SM Parcel Ground
DHLParcelExpedited DHL SM Parcel Expedited
DHLParcelExpeditedMax DHL SM Parcel Expedited Max
DHLBPMGround DHL SM Bound Printed Matter Ground
DHLBPMExpedited DHL SM Bound Printed Matter Expedited
DHLSmartMailParcelReturnGround DHL SM Parcel Return Ground
DHLSmartMailParcelReturnPlus DHL SM Parcel Return Plus
DHLSmartMailParcelReturnLight DHL SM Parcel Return Light
DHLPacketInternational DHL Packet International
DHLParcelInternationalStandard DHL Parcel International Standard
DHLParcelInternationalDirect DHL Parcel International Direct
DHLParcelInternationalDirectPriority DHL Parcel International Direct Priority
DHLParcelInternationalDirectStandard DHL Parcel International Direct Standard
DHLParcelInternationalDirectSMB DHL Parcel International Direct SMB
DHLParcelInternationalStandardSMB DHL Parcel International Standard SMB

Services

Service Name
Amazon Shipping Ground Amazon Shipping Ground

Create a Shipment

POST/api/v1/shipments

curl -X POST https://www.vanlo.com/api/v1/shipments \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "shipment": {
        "reference": "order-1042",
        "custom_id": "order-1042",
        "to_address": {
          "name": "John Doe",
          "street1": "148 W 51st St",
          "street2": "Apt 4B",
          "city": "New York",
          "state": "NY",
          "zip": "10019",
          "country": "US",
          "phone": "2125550199",
          "email": "john.doe@example.com",
          "residential": true
        },
        "from_address": {
          "name": "Jane Smith",
          "company": "Acme Goods",
          "street1": "417 Montgomery St",
          "street2": "Floor 5",
          "city": "San Francisco",
          "state": "CA",
          "zip": "94104",
          "country": "US",
          "phone": "4155550100",
          "email": "shipping@acme.example"
        },
        "parcel": {
          "length": 10.0,
          "width": 8.0,
          "height": 4.0,
          "weight": 32.0
        },
        "carrier_accounts": [
          "ca_..."
        ],
        "options": {
          "label_format": "PDF",
          "label_size": "4X6",
          "label_date": "2026-10-20",
          "delivery_confirmation": "SIGNATURE",
          "print_custom": [
            {
              "name": "Order",
              "value": "1042"
            }
          ]
        }
      }
    }'

# OR reference previously created objects

curl -X POST https://www.vanlo.com/api/v1/shipments \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "shipment": {
        "to_address": {
          "id": "adr_..."
        },
        "from_address": {
          "id": "adr_..."
        },
        "parcel": {
          "id": "prcl_..."
        },
        "customs_info": {
          "id": "cstinfo_..."
        }
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Shipment.create(
  reference: 'order-1042',
  custom_id: 'order-1042',
  to_address: {
    name: 'John Doe',
    street1: '148 W 51st St',
    street2: 'Apt 4B',
    city: 'New York',
    state: 'NY',
    zip: '10019',
    country: 'US',
    phone: '2125550199',
    email: 'john.doe@example.com',
    residential: true
  },
  from_address: {
    name: 'Jane Smith',
    company: 'Acme Goods',
    street1: '417 Montgomery St',
    street2: 'Floor 5',
    city: 'San Francisco',
    state: 'CA',
    zip: '94104',
    country: 'US',
    phone: '4155550100',
    email: 'shipping@acme.example'
  },
  parcel: {
    length: 10.0,
    width: 8.0,
    height: 4.0,
    weight: 32.0
  },
  carrier_accounts: ['ca_...'],
  options: {
    label_format: 'PDF',
    label_size: '4X6',
    label_date: '2026-10-20',
    delivery_confirmation: 'SIGNATURE',
    print_custom: [
      {
        name: 'Order',
        value: '1042'
      }
    ]
  }
)

# OR reference previously created objects

Vanlo::Shipment.create(
  to_address: { id: 'adr_...' },
  from_address: { id: 'adr_...' },
  parcel: { id: 'prcl_...' },
  customs_info: { id: 'cstinfo_...' }
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

shipment = vanlo.Shipment.create(
  reference="order-1042",
  custom_id="order-1042",
  to_address={
    "name": "John Doe",
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": True
  },
  from_address={
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example"
  },
  parcel={
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "weight": 32.0
  },
  carrier_accounts=["ca_..."],
  options={
    "label_format": "PDF",
    "label_size": "4X6",
    "label_date": "2026-10-20",
    "delivery_confirmation": "SIGNATURE",
    "print_custom": [
      {
        "name": "Order",
        "value": "1042"
      }
    ]
  }
)

# OR reference previously created objects

shipment = vanlo.Shipment.create(
  to_address={"id": "adr_..."},
  from_address={"id": "adr_..."},
  parcel={"id": "prcl_..."},
  customs_info={"id": "cstinfo_..."}
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$shipment = \Vanlo\Shipment::create(array(
  'reference' => 'order-1042',
  'custom_id' => 'order-1042',
  'to_address' => array(
    'name' => 'John Doe',
    'street1' => '148 W 51st St',
    'street2' => 'Apt 4B',
    'city' => 'New York',
    'state' => 'NY',
    'zip' => '10019',
    'country' => 'US',
    'phone' => '2125550199',
    'email' => 'john.doe@example.com',
    'residential' => true
  ),
  'from_address' => array(
    'name' => 'Jane Smith',
    'company' => 'Acme Goods',
    'street1' => '417 Montgomery St',
    'street2' => 'Floor 5',
    'city' => 'San Francisco',
    'state' => 'CA',
    'zip' => '94104',
    'country' => 'US',
    'phone' => '4155550100',
    'email' => 'shipping@acme.example'
  ),
  'parcel' => array(
    'length' => 10.0,
    'width' => 8.0,
    'height' => 4.0,
    'weight' => 32.0
  ),
  'carrier_accounts' => array('ca_...'),
  'options' => array(
    'label_format' => 'PDF',
    'label_size' => '4X6',
    'label_date' => '2026-10-20',
    'delivery_confirmation' => 'SIGNATURE',
    'print_custom' => array(
      array(
        'name' => 'Order',
        'value' => '1042'
      )
    )
  )
));

// OR reference previously created objects

$shipment = \Vanlo\Shipment::create(array(
  'to_address' => array('id' => 'adr_...'),
  'from_address' => array('id' => 'adr_...'),
  'parcel' => array('id' => 'prcl_...'),
  'customs_info' => array('id' => 'cstinfo_...')
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Shipment shipment = Shipment.Create(new Dictionary<string, object>() {
    { "reference", "order-1042" },
    { "custom_id", "order-1042" },
    { "to_address", new Dictionary<string, object>() {
        { "name", "John Doe" },
        { "street1", "148 W 51st St" },
        { "street2", "Apt 4B" },
        { "city", "New York" },
        { "state", "NY" },
        { "zip", "10019" },
        { "country", "US" },
        { "phone", "2125550199" },
        { "email", "john.doe@example.com" },
        { "residential", true }
    } },
    { "from_address", new Dictionary<string, object>() {
        { "name", "Jane Smith" },
        { "company", "Acme Goods" },
        { "street1", "417 Montgomery St" },
        { "street2", "Floor 5" },
        { "city", "San Francisco" },
        { "state", "CA" },
        { "zip", "94104" },
        { "country", "US" },
        { "phone", "4155550100" },
        { "email", "shipping@acme.example" }
    } },
    { "parcel", new Dictionary<string, object>() {
        { "length", 10.0 },
        { "width", 8.0 },
        { "height", 4.0 },
        { "weight", 32.0 }
    } },
    { "carrier_accounts", new List<string>() { "ca_..." } },
    { "options", new Dictionary<string, object>() {
        { "label_format", "PDF" },
        { "label_size", "4X6" },
        { "label_date", "2026-10-20" },
        { "delivery_confirmation", "SIGNATURE" },
        { "print_custom", new List<Dictionary<string, object>>() {
            new Dictionary<string, object>() {
                { "name", "Order" },
                { "value", "1042" }
            }
        } }
    } }
});

// OR reference previously created objects

Shipment shipment = Shipment.Create(new Dictionary<string, object>() {
    { "to_address", new Dictionary<string, object>() {
        { "id", "adr_..." }
    } },
    { "from_address", new Dictionary<string, object>() {
        { "id", "adr_..." }
    } },
    { "parcel", new Dictionary<string, object>() {
        { "id", "prcl_..." }
    } },
    { "customs_info", new Dictionary<string, object>() {
        { "id", "cstinfo_..." }
    } }
});

Creates a shipment and returns it with a rate for each service your carrier accounts offer. Buy one of the rates to purchase the label, or send service with options.create_and_buy to buy in the same request.

Parameters

Parameter Type Specification
from_addressrequired Address Your warehouse address
to_addressrequired Address Recipient address
parcelrequired Parcel Package properties. To ship several packages from one address to one recipient, create an Order.
customs_info CustomsInfo Only required for international shipments and shipments to APO/DPO/FPO.
options Options Shipment options. On an international shipment that may ship with FedEx or UPS, send options.duty_payment to say who pays duties and taxes.
service string The service to buy. With options.create_and_buy the label is bought in the same request; without it only this service is rated, and its rate is set as selected_rate.
carrier string A carrier name, such as USPS, to rate only that carrier's accounts. Ignored when carrier_accounts is sent.
carrier_accounts string[] One or more Carrier Account ids to get rates from. Without it, or carrier, every account you hold rates the shipment, narrowed to the accounts offering service when one is sent.
reference string Arbitrary string that you can use later to look up the shipment or filter all the shipments with the same reference to include in a ScanForm.
custom_id string Your key for this shipment. While the shipment can still be bought, sending the same custom_id again updates it instead of creating another one. After that it answers 409 CONFLICT with the shipment.
return_address Address Distinct return address if it differs from from_address.
is_return boolean Set true to create a return shipment. The same as options.is_return.
buyer_address Address Distinct buyer address if it differs from to_address.

Returns

Response:

{
  "id": "shp_...",
  "object": "Shipment",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:04:12Z",
  "reference": "order-1042",
  "usps_zone": 8,
  "custom_id": "order-1042",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "return_address": null,
  "buyer_address": null,
  "parcel": {
    "id": "prcl_...",
    "object": "Parcel",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "predefined_package": null,
    "weight": 32.0
  },
  "customs_info": null,
  "rates": [
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "GroundAdvantage",
      "delivery_date": "2026-10-26",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 6,
      "rate": "9.84",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DUXX0XXXXC08020",
        "quoted_service": "GroundAdvantage",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "12.47",
        "discount": "2.63",
        "discount_date": "2026-09-29",
        "total_freight": "9.84",
        "total_surcharges": "0.00",
        "services": {
          "DUXX0XXXXC08020": 12.47
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Priority",
      "delivery_date": "2026-10-23",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 3,
      "rate": "11.20",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DPXX0XXXXC08020",
        "quoted_service": "Priority",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "14.95",
        "discount": "3.75",
        "discount_date": "2026-09-29",
        "total_freight": "11.20",
        "total_surcharges": "0.00",
        "services": {
          "DPXX0XXXXC08020": 14.95
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Express",
      "delivery_date": "2026-10-22",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 2,
      "rate": "48.75",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DEXX0XXXXC08020",
        "quoted_service": "Express",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "52.30",
        "discount": "3.55",
        "discount_date": "2026-09-29",
        "total_freight": "48.75",
        "total_surcharges": "0.00",
        "services": {
          "DEXX0XXXXC08020": 52.3
        },
        "rdc": "04"
      },
      "usps_cubic": false
    }
  ],
  "selected_rate": null,
  "tracker": null,
  "postage_label": null,
  "refund_status": null,
  "tracking_code": null,
  "status": null,
  "insurance": null,
  "is_return": null,
  "options": {
    "delivery_confirmation": "SIGNATURE",
    "label_format": "pdf",
    "label_size": "4X6",
    "label_date": "2026-10-20",
    "print_custom": [
      {
        "name": "Order",
        "value": "1042"
      }
    ]
  }
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "to_address",
        "message": "is missing"
      }
    ]
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Address not found by id for to_address field. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for INVALID_OPTIONS:

{
  "error": {
    "code": "INVALID_OPTIONS",
    "message": "Invalid options. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "options",
        "message": "label_format must be one of: png, pdf, zpl, epl2"
      }
    ]
  }
}

Response for CONFLICT:

{
  "id": "shp_...",
  "object": "Shipment",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "reference": "order-1042",
  "usps_zone": "08",
  "custom_id": "order-1042",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "return_address": null,
  "buyer_address": null,
  "parcel": {
    "id": "prcl_...",
    "object": "Parcel",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "predefined_package": null,
    "weight": 32.0
  },
  "customs_info": null,
  "rates": [
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "GroundAdvantage",
      "delivery_date": "2026-10-26",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 6,
      "rate": "9.84",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DUXX0XXXXC08020",
        "quoted_service": "GroundAdvantage",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "12.47",
        "discount": "2.63",
        "discount_date": "2026-09-29",
        "total_freight": "9.84",
        "total_surcharges": "0.00",
        "services": {
          "DUXX0XXXXC08020": 12.47
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Priority",
      "delivery_date": "2026-10-23",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 3,
      "rate": "11.20",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DPXX0XXXXC08020",
        "quoted_service": "Priority",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "14.95",
        "discount": "3.75",
        "discount_date": "2026-09-29",
        "total_freight": "11.20",
        "total_surcharges": "0.00",
        "services": {
          "DPXX0XXXXC08020": 14.95
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Express",
      "delivery_date": "2026-10-22",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 2,
      "rate": "48.75",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DEXX0XXXXC08020",
        "quoted_service": "Express",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "52.30",
        "discount": "3.55",
        "discount_date": "2026-09-29",
        "total_freight": "48.75",
        "total_surcharges": "0.00",
        "services": {
          "DEXX0XXXXC08020": 52.3
        },
        "rdc": "04"
      },
      "usps_cubic": false
    }
  ],
  "selected_rate": {
    "id": "rate_...",
    "object": "Rate",
    "carrier_account_id": "ca_...",
    "shipment_id": "shp_...",
    "created_at": "2026-10-20T15:04:12Z",
    "service": "Priority",
    "delivery_date": "2026-10-23",
    "delivery_datetime": null,
    "delivery_date_guaranteed": false,
    "delivery_days": 3,
    "rate": "11.20",
    "carrier": "USPS",
    "rate_detail": {
      "zone": "08",
      "sku": "DPXX0XXXXC08020",
      "quoted_service": "Priority",
      "billing_weight": "32.0 OZ",
      "non_cubic_weight": "32.0 OZ",
      "volume": 320.0,
      "usps_cubic": false,
      "commercial_freight": "14.95",
      "discount": "3.75",
      "discount_date": "2026-09-29",
      "total_freight": "11.20",
      "total_surcharges": "0.00",
      "services": {
        "DPXX0XXXXC08020": 14.95
      },
      "rdc": "04"
    },
    "usps_cubic": false
  },
  "tracker": {
    "id": "trk_...",
    "object": "Tracker",
    "shipment_id": "shp_...",
    "tracking_details": [],
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "status": "unknown",
    "carrier": "USPS",
    "tracking_code": "9405500106024190341287",
    "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
  },
  "postage_label": {
    "object": "PostageLabel",
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "id": "pl_...",
    "integrated_form": null,
    "label_date": "2026-10-20",
    "label_epl2_url": null,
    "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_resolution": null,
    "label_size": null,
    "label_type": null,
    "label_file_type": "application/pdf",
    "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_zpl_url": null
  },
  "refund_status": null,
  "tracking_code": "9405500106024190341287",
  "status": null,
  "insurance": null,
  "is_return": null,
  "options": {
    "delivery_confirmation": "SIGNATURE",
    "label_format": "pdf",
    "label_size": "4X6",
    "label_date": "2026-10-20",
    "print_custom": [
      {
        "name": "Order",
        "value": "1042"
      }
    ]
  },
  "error": {
    "code": "CONFLICT",
    "message": "A shipment with this custom_id already exists and cannot be updated. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for PAYMENT_REQUIRED:

{
  "error": {
    "code": "PAYMENT_REQUIRED",
    "message": "Insufficient funds. Please check your billing settings at http://www.vanlo.com/balance. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Balance",
        "message": "Your balance is too low to purchase this label. Please add funds on the Balance page before buying."
      }
    ]
  }
}

Response for CARRIER_REJECTED_ADDRESS:

{
  "error": {
    "code": "CARRIER_REJECTED_ADDRESS",
    "message": "USPS rejected this shipment: bad zip code. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "USPS rejected this shipment: bad zip code"
      }
    ]
  }
}

Response for EXTERNAL_SERVICE_ERROR:

{
  "error": {
    "code": "EXTERNAL_SERVICE_ERROR",
    "message": "OnTrac could not create this label. Please contact support if it does not clear. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "OnTrac could not create this label. Please contact support if it does not clear."
      }
    ]
  }
}

Response for TOO_MANY_REQUESTS:

{
  "error": {
    "code": "TOO_MANY_REQUESTS",
    "message": "Too many label purchases in flight for this account. Please retry shortly. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [],
    "details": {
      "retry_after": 2
    }
  }
}

Returns the Shipment with a rate for each available service, and with the label already bought when options.create_and_buy is set.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A required field is missing or has the wrong shape, such as no to_address or a parcel without weight and dimensions. error.errors names each field.
NOT_FOUND 404 An address, parcel or customs info sent by id is not one of yours.
INVALID_OPTIONS 422 An options value is not allowed, such as an unknown label_format, a hazmat value the carrier does not take, or a malformed duty_payment.
CONFLICT 409 The custom_id belongs to a shipment that can no longer be updated. That shipment is returned beside error.
PAYMENT_REQUIRED 402 With options.create_and_buy, your balance does not cover the label.
CARRIER_REJECTED_ADDRESS 422 The carrier refused the destination address. error.message carries its reason.
EXTERNAL_SERVICE_ERROR 424 The carrier rejected or failed the request. error.message carries its reason.
TOO_MANY_REQUESTS 429 Too many label purchases are running for your account at once. The Retry-After header gives the wait in seconds.

Retrying a create or a purchase after a timeout is covered in the Retries and Timeouts Guide.

Buy a Shipment

POST/api/v1/shipments/:id/buy

curl -X POST https://www.vanlo.com/api/v1/shipments/shp_.../buy \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
        "rate": {
          "id": "rate_..."
        }
      }'
require 'vanlo'
Vanlo.api_key = "VANLO_API_KEY"

shipment = Vanlo::Shipment.retrieve("shp_...")
shipment.buy(rate: shipment.lowest_rate)
import vanlo
vanlo.api_key = "VANLO_API_KEY"

shipment = vanlo.Shipment.retrieve("shp_...")
shipment.buy(rate=shipment.lowest_rate())
require_once("path/to/lib/vanlo.php");
\Vanlo\Vanlo::setApiKey("VANLO_API_KEY");

$shipment = \Vanlo\Shipment::retrieve("shp_...");
$shipment->buy(array(
  'rate'      => $shipment->lowest_rate()
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Shipment shipment = Shipment.Retrieve("shp_...");
Rate lowestRate = shipment.LowestRate();

shipment.Buy(lowestRate);

Buys the label for one of the shipment's rates, in the format of the shipment's options.label_format.

Parameters

Parameter Type Specification
rate object The rate to buy, as { "id": "rate_..." }

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Postage already exists for this shipment. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for PAYMENT_REQUIRED:

{
  "error": {
    "code": "PAYMENT_REQUIRED",
    "message": "Insufficient funds. Please check your billing settings at http://www.vanlo.com/balance. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Balance",
        "message": "Your balance is too low to purchase this label. Please add funds on the Balance page before buying."
      }
    ]
  }
}

Response for RATE_EXPIRED:

{
  "error": {
    "code": "RATE_EXPIRED",
    "message": "Rate expired. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "Rate expired"
      }
    ]
  }
}

Response for CARRIER_REJECTED_ADDRESS:

{
  "error": {
    "code": "CARRIER_REJECTED_ADDRESS",
    "message": "USPS rejected this shipment: bad zip code. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "USPS rejected this shipment: bad zip code"
      }
    ]
  }
}

Response for VALIDATION_ERROR:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The maximum per package weight for the selected service from the selected country or territory is 150 pounds. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "The maximum per package weight for the selected service from the selected country or territory is 150 pounds."
      }
    ]
  }
}

Response for LOCKED:

{
  "error": {
    "code": "LOCKED",
    "message": "Another resource is creating at the moment. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "LockedError",
        "message": "This shipment is already being purchased. Please wait for it to finish."
      }
    ]
  }
}

Response for EXTERNAL_SERVICE_ERROR:

{
  "error": {
    "code": "EXTERNAL_SERVICE_ERROR",
    "message": "OnTrac could not create this label. Please contact support if it does not clear. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "OnTrac could not create this label. Please contact support if it does not clear."
      }
    ]
  }
}

Response for TOO_MANY_REQUESTS:

{
  "error": {
    "code": "TOO_MANY_REQUESTS",
    "message": "Too many label purchases in flight for this account. Please retry shortly. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [],
    "details": {
      "retry_after": 2
    }
  }
}

Returns the Shipment with selected_rate, postage_label, tracker and tracking_code filled in.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 The shipment already has a label, or is past its 72-hour purchase window.
NOT_FOUND 404 No shipment has this id, or the rate is not one of its rates.
PAYMENT_REQUIRED 402 Your balance does not cover the label.
RATE_EXPIRED 409 The carrier no longer honours the rate.
CARRIER_REJECTED_ADDRESS 422 The carrier refused the destination address. error.message carries its reason.
VALIDATION_ERROR 422 The carrier refused the shipment as invalid, such as a parcel over the service's weight limit. error.message carries its reason.
LOCKED 429 This shipment is already being bought, or Vanlo is confirming an earlier purchase with the carrier.
EXTERNAL_SERVICE_ERROR 424 The carrier rejected or failed the request. error.message carries its reason.
TOO_MANY_REQUESTS 429 Too many label purchases are running for your account at once. The Retry-After header gives the wait in seconds.

Refund a Shipment

POST/api/v1/shipments/:id/refund

curl -X POST https://www.vanlo.com/api/v1/shipments/shp_.../refund \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = "VANLO_API_KEY"

shipment = Vanlo::Shipment.retrieve("shp_...")
shipment.refund
import vanlo
vanlo.api_key = "VANLO_API_KEY"

shipment = vanlo.Shipment.retrieve("shp_...")
shipment.refund()
require_once("path/to/lib/vanlo.php");
\Vanlo\Vanlo::setApiKey("VANLO_API_KEY");

$shipment = \Vanlo\Shipment::retrieve("shp_...");
$shipment->refund();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Shipment shipment = Shipment.Retrieve("shp_...");
shipment.Refund();

Asks the carrier to cancel the label and refund its cost.

Parameters

Parameter Type Specification
id string Unique identifier of the shipment to refund

Returns

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for VALIDATION_ERROR:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Return label orders cannot be canceled. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for EXTERNAL_SERVICE_ERROR:

{
  "error": {
    "code": "EXTERNAL_SERVICE_ERROR",
    "message": "Unexpected response from our service provider has been received while processing your request. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Shipment with refund_status set: submitted while the carrier decides, then refunded or rejected. A refund the carrier declines is not an error.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No shipment has this id.
VALIDATION_ERROR 422 The carrier will not cancel this kind of label, such as a return label. error.message carries its reason.
EXTERNAL_SERVICE_ERROR 424 The carrier failed to answer the cancel request.

List Shipments

GET/api/v1/shipments

curl -G https://www.vanlo.com/api/v1/shipments \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -d 'page_size=5' \
  -d 'purchased=true'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Shipment.all(page_size: 5)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Shipment.all(page_size=5)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$shipments = \Vanlo\Shipment::all(array('page_size' => 5));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

var listParams = new Dictionary<string, object>() {
    { "page_size", 5 }
};

ShipmentList shipmentList = Shipment.List(listParams);

Lists your shipments a page at a time. Pass before_id or after_id to say where the next page begins.

Parameters

Parameter Type Specification
purchased boolean When present, only return purchased shipments (shipments with a tracking code)
before_id string Return shipments created before this id
after_id string Return shipments created after this id
start_datetime datetime Only return shipments created after this timestamp
end_datetime datetime Only return shipments created before this timestamp
page_size integer Number of shipments to return per page (default 20, max 100)

Returns

Response:

{
  "shipments": [
    {
      "id": "shp_...",
      "object": "Shipment",
      "created_at": "2026-10-20T15:04:12Z",
      "updated_at": "2026-10-20T15:06:40Z",
      "reference": "order-1042",
      "usps_zone": "08",
      "custom_id": "order-1042",
      "from_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "to_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "John Doe",
        "company": null,
        "street1": "148 W 51st St",
        "street2": "Apt 4B",
        "city": "New York",
        "state": "NY",
        "zip": "10019",
        "country": "US",
        "phone": "2125550199",
        "email": "john.doe@example.com",
        "residential": true,
        "verifications": null
      },
      "return_address": null,
      "buyer_address": null,
      "parcel": {
        "id": "prcl_...",
        "object": "Parcel",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "length": 10.0,
        "width": 8.0,
        "height": 4.0,
        "predefined_package": null,
        "weight": 32.0
      },
      "customs_info": null,
      "rates": [
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "GroundAdvantage",
          "delivery_date": "2026-10-26",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 6,
          "rate": "9.84",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DUXX0XXXXC08020",
            "quoted_service": "GroundAdvantage",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "12.47",
            "discount": "2.63",
            "discount_date": "2026-09-29",
            "total_freight": "9.84",
            "total_surcharges": "0.00",
            "services": {
              "DUXX0XXXXC08020": 12.47
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Priority",
          "delivery_date": "2026-10-23",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 3,
          "rate": "11.20",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DPXX0XXXXC08020",
            "quoted_service": "Priority",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "14.95",
            "discount": "3.75",
            "discount_date": "2026-09-29",
            "total_freight": "11.20",
            "total_surcharges": "0.00",
            "services": {
              "DPXX0XXXXC08020": 14.95
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Express",
          "delivery_date": "2026-10-22",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 2,
          "rate": "48.75",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DEXX0XXXXC08020",
            "quoted_service": "Express",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "52.30",
            "discount": "3.55",
            "discount_date": "2026-09-29",
            "total_freight": "48.75",
            "total_surcharges": "0.00",
            "services": {
              "DEXX0XXXXC08020": 52.3
            },
            "rdc": "04"
          },
          "usps_cubic": false
        }
      ],
      "selected_rate": {
        "id": "rate_...",
        "object": "Rate",
        "carrier_account_id": "ca_...",
        "shipment_id": "shp_...",
        "created_at": "2026-10-20T15:04:12Z",
        "service": "Priority",
        "delivery_date": "2026-10-23",
        "delivery_datetime": null,
        "delivery_date_guaranteed": false,
        "delivery_days": 3,
        "rate": "11.20",
        "carrier": "USPS",
        "rate_detail": {
          "zone": "08",
          "sku": "DPXX0XXXXC08020",
          "quoted_service": "Priority",
          "billing_weight": "32.0 OZ",
          "non_cubic_weight": "32.0 OZ",
          "volume": 320.0,
          "usps_cubic": false,
          "commercial_freight": "14.95",
          "discount": "3.75",
          "discount_date": "2026-09-29",
          "total_freight": "11.20",
          "total_surcharges": "0.00",
          "services": {
            "DPXX0XXXXC08020": 14.95
          },
          "rdc": "04"
        },
        "usps_cubic": false
      },
      "tracker": {
        "id": "trk_...",
        "object": "Tracker",
        "shipment_id": "shp_...",
        "tracking_details": [],
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "status": "unknown",
        "carrier": "USPS",
        "tracking_code": "9405500106024190341287",
        "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
      },
      "postage_label": {
        "object": "PostageLabel",
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "id": "pl_...",
        "integrated_form": null,
        "label_date": "2026-10-20",
        "label_epl2_url": null,
        "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_resolution": null,
        "label_size": null,
        "label_type": null,
        "label_file_type": "application/pdf",
        "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_zpl_url": null
      },
      "refund_status": null,
      "tracking_code": "9405500106024190341287",
      "status": null,
      "insurance": null,
      "is_return": null,
      "options": {
        "delivery_confirmation": "SIGNATURE",
        "label_format": "pdf",
        "label_size": "4X6",
        "label_date": "2026-10-20",
        "print_custom": [
          {
            "name": "Order",
            "value": "1042"
          }
        ]
      }
    }
  ],
  "has_more": true
}

Returns an object with shipments, an array of Shipment, and has_more, which says whether another page exists.

On failure it returns one of the common errors; this call has none of its own.

Retrieve a Shipment

GET/api/v1/shipments/:id

curl https://www.vanlo.com/api/v1/shipments/shp_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Shipment.retrieve('shp_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Shipment.retrieve('shp_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$shipment = \Vanlo\Shipment::retrieve('shp_...');
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Shipment shipment = Shipment.Retrieve("shp_...");

Retrieves a shipment by its id, or by its tracking_code, custom_id or reference.

Parameters

Parameter Type Specification
id string Unique identifier of the shipment, or a tracking code, custom_id, or reference

Returns

Response:

{
  "id": "shp_...",
  "object": "Shipment",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "reference": "order-1042",
  "usps_zone": "08",
  "custom_id": "order-1042",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "return_address": null,
  "buyer_address": null,
  "parcel": {
    "id": "prcl_...",
    "object": "Parcel",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "predefined_package": null,
    "weight": 32.0
  },
  "customs_info": null,
  "rates": [
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "GroundAdvantage",
      "delivery_date": "2026-10-26",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 6,
      "rate": "9.84",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DUXX0XXXXC08020",
        "quoted_service": "GroundAdvantage",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "12.47",
        "discount": "2.63",
        "discount_date": "2026-09-29",
        "total_freight": "9.84",
        "total_surcharges": "0.00",
        "services": {
          "DUXX0XXXXC08020": 12.47
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Priority",
      "delivery_date": "2026-10-23",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 3,
      "rate": "11.20",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DPXX0XXXXC08020",
        "quoted_service": "Priority",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "14.95",
        "discount": "3.75",
        "discount_date": "2026-09-29",
        "total_freight": "11.20",
        "total_surcharges": "0.00",
        "services": {
          "DPXX0XXXXC08020": 14.95
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Express",
      "delivery_date": "2026-10-22",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 2,
      "rate": "48.75",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DEXX0XXXXC08020",
        "quoted_service": "Express",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "52.30",
        "discount": "3.55",
        "discount_date": "2026-09-29",
        "total_freight": "48.75",
        "total_surcharges": "0.00",
        "services": {
          "DEXX0XXXXC08020": 52.3
        },
        "rdc": "04"
      },
      "usps_cubic": false
    }
  ],
  "selected_rate": {
    "id": "rate_...",
    "object": "Rate",
    "carrier_account_id": "ca_...",
    "shipment_id": "shp_...",
    "created_at": "2026-10-20T15:04:12Z",
    "service": "Priority",
    "delivery_date": "2026-10-23",
    "delivery_datetime": null,
    "delivery_date_guaranteed": false,
    "delivery_days": 3,
    "rate": "11.20",
    "carrier": "USPS",
    "rate_detail": {
      "zone": "08",
      "sku": "DPXX0XXXXC08020",
      "quoted_service": "Priority",
      "billing_weight": "32.0 OZ",
      "non_cubic_weight": "32.0 OZ",
      "volume": 320.0,
      "usps_cubic": false,
      "commercial_freight": "14.95",
      "discount": "3.75",
      "discount_date": "2026-09-29",
      "total_freight": "11.20",
      "total_surcharges": "0.00",
      "services": {
        "DPXX0XXXXC08020": 14.95
      },
      "rdc": "04"
    },
    "usps_cubic": false
  },
  "tracker": {
    "id": "trk_...",
    "object": "Tracker",
    "shipment_id": "shp_...",
    "tracking_details": [],
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "status": "unknown",
    "carrier": "USPS",
    "tracking_code": "9405500106024190341287",
    "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
  },
  "postage_label": {
    "object": "PostageLabel",
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "id": "pl_...",
    "integrated_form": null,
    "label_date": "2026-10-20",
    "label_epl2_url": null,
    "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_resolution": null,
    "label_size": null,
    "label_type": null,
    "label_file_type": "application/pdf",
    "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_zpl_url": null
  },
  "refund_status": null,
  "tracking_code": "9405500106024190341287",
  "status": null,
  "insurance": null,
  "is_return": null,
  "options": {
    "delivery_confirmation": "SIGNATURE",
    "label_format": "pdf",
    "label_size": "4X6",
    "label_date": "2026-10-20",
    "print_custom": [
      {
        "name": "Order",
        "value": "1042"
      }
    ]
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Shipment.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No shipment of yours matches the id, tracking code, custom_id or reference.

Dispute a Transaction

POST/api/v1/transactions/:id/dispute

curl -X POST https://www.vanlo.com/api/v1/transactions/paylog_.../dispute \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "reason": "INCORRECT_ASSESSED_WEIGHT",
      "description": "Package weighed 4 lbs, USPS billed for 7 lbs"
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

transaction = Vanlo::Transaction.retrieve('paylog_...')
transaction.dispute(
  reason: 'INCORRECT_ASSESSED_WEIGHT',
  description: 'Package weighed 4 lbs, USPS billed for 7 lbs'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

transaction = vanlo.Transaction.retrieve('paylog_...')
transaction.dispute(
    reason='INCORRECT_ASSESSED_WEIGHT',
    description='Package weighed 4 lbs, USPS billed for 7 lbs'
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$transaction = \Vanlo\Transaction::retrieve('paylog_...');
$transaction->dispute(array(
  'reason' => 'INCORRECT_ASSESSED_WEIGHT',
  'description' => 'Package weighed 4 lbs, USPS billed for 7 lbs'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Transaction transaction = Transaction.Retrieve("paylog_...");
transaction.Dispute("INCORRECT_ASSESSED_WEIGHT", "Package weighed 4 lbs, USPS billed for 7 lbs");

Disputes an adjustment USPS made after a shipment, such as a reassessment of its weight, zone or dimensions. Vanlo files it with USPS, and a refund for an accepted dispute is credited to your account.

Parameters

Parameter Type Specification
reasonrequired string Reason for the dispute. USPS accepts INCORRECT_ASSESSED_WEIGHT, INCORRECT_ASSESSED_ZONE, INCORRECT_ASSESSED_PACKAGING, INCORRECT_ASSESSED_DIMENSIONS, INCORRECT_ASSESSED_DUPLICATE, UNDOCUMENTED, NONCOMPLIANT_DIMENSIONS, RETURN_LABEL, MISSHIPPED, or OTHER.
description string Free-text description providing more context for the dispute. Defaults to the reason when omitted.

Returns

Response:

{
  "id": 123,
  "dispute_id": "DSP-2026-001",
  "status": "NEW",
  "reason": "INCORRECT_ASSESSED_WEIGHT",
  "message": "Dispute submitted to USPS"
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "This charge can't be disputed through USPS. USPS only reviews disputes for adjustments it makes after a shipment (its reassessments of weight, zone, or dimensions). Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the dispute: its dispute_id at USPS and its status.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 The charge is not a USPS adjustment, such as the original purchase, a duplicate charge or a failed refund, or it was already disputed, or reason is missing.
NOT_FOUND 404 No transaction of yours has this id.

Nested Objects

Objects a Shipment carries or accepts. Each one also expands in place wherever a table names it.

Rate Object

A Rate:

{
  "id": "rate_...",
  "object": "Rate",
  "carrier_account_id": "ca_...",
  "shipment_id": "shp_...",
  "created_at": "2026-10-20T15:04:12Z",
  "service": "Priority",
  "delivery_date": "2026-10-23",
  "delivery_datetime": null,
  "delivery_date_guaranteed": false,
  "delivery_days": 3,
  "rate": "11.20",
  "carrier": "USPS",
  "rate_detail": {
    "zone": "08",
    "sku": "DPXX0XXXXC08020",
    "quoted_service": "Priority",
    "billing_weight": "32.0 OZ",
    "non_cubic_weight": "32.0 OZ",
    "volume": 320.0,
    "usps_cubic": false,
    "commercial_freight": "14.95",
    "discount": "3.75",
    "discount_date": "2026-09-29",
    "total_freight": "11.20",
    "total_surcharges": "0.00",
    "services": {
      "DPXX0XXXXC08020": 14.95
    },
    "rdc": "04"
  },
  "usps_cubic": false
}
Parameter Type Specification
id string Unique identifier, begins with 'rate_'
object string "Rate"
carrier string Name of the carrier
service string Name of the service. Each carrier's services are listed under Carrier Services
rate string The price of this service, in USD
rate_detail object How the rate was priced: total_freight and total_surcharges, the zone, billing_weight and sku, and on a discounted USPS rate the commercial_freight before the discount. Each carrier's fees are listed under Carrier Services
shipment_id string The shipment this rate belongs to, or null on a quote
carrier_account_id string The Carrier Account that priced this rate
delivery_date string Estimated delivery date, when the carrier gives one
delivery_datetime datetime Estimated delivery date and time, when the carrier gives one
delivery_date_guaranteed boolean Whether the carrier guarantees the delivery date
delivery_days integer Estimated days in transit, when the carrier gives them
usps_cubic boolean Whether the rate is USPS cubic pricing. Present only on rates that carry the flag
created_at datetime When the rate was created

PostageLabel Object

A PostageLabel:

{
  "object": "PostageLabel",
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "id": "pl_...",
  "integrated_form": null,
  "label_date": "2026-10-20",
  "label_epl2_url": null,
  "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
  "label_resolution": null,
  "label_size": null,
  "label_type": null,
  "label_file_type": "application/pdf",
  "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
  "label_zpl_url": null
}
Parameter Type Specification
id string Unique identifier, begins with 'pl_'
object string "PostageLabel"
integrated_form string Always null
label_date string The ship date printed on the label, as YYYY-MM-DD
label_epl2_url string Always null
label_pdf_url string URL of the PDF label, when one exists
label_zpl_url string URL of the ZPL label, when one exists
label_resolution string Always null
label_size string Always null
label_type string Always null
label_file_type string Label file type. Ends in " - base64" when label_file holds the label
label_file string The label itself, base64-encoded, when the shipment was bought with postage_label_inline. label_url is then null
label_url string URL of the label in the format it was bought in
created_at datetime When the label was created
updated_at datetime When the label was last updated

Options Object

Every option, across carriers:

{
  "bag_number": "BAG-07",
  "batch_number": "B-20261020-01",
  "buzz_code": "1042",
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "delivery_instructions": "Leave with the concierge",
  "driver_notes": "Leave at the front desk",
  "duty_payment": {
    "type": "THIRD_PARTY",
    "account": "123456789",
    "country": "US",
    "postal_code": "10001"
  },
  "endorsement": "RETURN_SERVICE",
  "fetch_express_delivery_date": true,
  "hazmat": "LITHIUM",
  "hub_id": 12,
  "insurance_amount": 150.0,
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "machinable": false,
  "pickup_begin_time": "2026-10-20T20:00:00",
  "pickup_end_time": "2026-10-20T22:00:00",
  "pickup_type": "LaserShip",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ],
  "saturday_delivery": true,
  "smartpost_hub": "5531",
  "smartpost_manifest": "02912345",
  "special_rates_eligibility": "USPS.MEDIAMAIL",
  "total_value": 45.0
}

Options for USPS:

{
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "fetch_express_delivery_date": true,
  "hazmat": "LITHIUM",
  "insurance_amount": 150.0,
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "machinable": false,
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ],
  "special_rates_eligibility": "USPS.MEDIAMAIL"
}

Options for FedEx:

{
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "duty_payment": {
    "type": "THIRD_PARTY",
    "account": "123456789",
    "country": "US",
    "postal_code": "10001"
  },
  "endorsement": "RETURN_SERVICE",
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ],
  "saturday_delivery": true,
  "smartpost_hub": "5531",
  "smartpost_manifest": "02912345"
}

Options for UPS:

{
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "duty_payment": {
    "type": "THIRD_PARTY",
    "account": "123456789",
    "country": "US",
    "postal_code": "10001"
  },
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ]
}

Options for UniUni:

{
  "bag_number": "BAG-07",
  "batch_number": "B-20261020-01",
  "buzz_code": "1042",
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "driver_notes": "Leave at the front desk",
  "hub_id": 12,
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ],
  "total_value": 45.0
}

Options for OSM:

{
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ]
}

Options for OneParcel:

{
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ]
}

Options for DoorDash:

{
  "create_and_buy": true,
  "delivery_instructions": "Leave with the concierge",
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "pickup_begin_time": "2026-10-20T20:00:00",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ],
  "total_value": 45.0
}

Options for OnTrac:

{
  "carrier_insurance_amount": 150.0,
  "create_and_buy": true,
  "delivery_confirmation": "SIGNATURE",
  "delivery_instructions": "Leave with the concierge",
  "is_return": false,
  "label_date": "2026-10-20T09:00:00-07:00",
  "label_format": "PDF",
  "label_size": "4X6",
  "pickup_begin_time": "2026-10-20T20:00:00",
  "pickup_end_time": "2026-10-20T22:00:00",
  "pickup_type": "LaserShip",
  "postage_label_inline": true,
  "print_custom": [
    {
      "name": "Order",
      "value": "1042"
    }
  ],
  "total_value": 45.0
}

Every option a shipment accepts. A badge marks an option only some carriers accept; pick a carrier to see just its options and values.

Parameter Type Specification
bag_number
UniUni
string Bag number printed on the label.
batch_number
UniUni
string Batch to associate the shipment with.
buzz_code
UniUni
string Recipient's buzz code printed on the label.
carrier_insurance_amount float Declared value in USD, to buy the carrier's insurance. Cannot be combined with insurance_amount.
OnTracUsed ahead of total_value.
create_and_buy boolean Set to true to create and buy the label in one request, with the service sent beside it.
delivery_confirmation string Signature required at delivery.
USPSNO_SIGNATUREdefault SIGNATURE ADULT_SIGNATURE SIGNATURE_RESTRICTED ADULT_SIGNATURE_RESTRICTED
OnTracNO_SIGNATUREdefault SIGNATURE ADULT_SIGNATURE ADULT_SIGNATURE_RESTRICTED
OnTracSIGNATURE_RESTRICTED is treated as NO_SIGNATURE.
delivery_instructions
DoorDashOnTrac
string Instructions for the driver at the drop-off.
driver_notes
UniUni
string Notes for the driver printed on the label.
duty_payment
FedExUPS
DutyPayment Who pays duties and taxes on an international shipment.
endorsement
FedEx
string Ancillary endorsement for SmartPost.
ValuesADDRESS_CORRECTION CARRIER_LEAVE_IF_NO_RESPONSE CHANGE_SERVICE FORWARDING_SERVICE RETURN_SERVICE
fetch_express_delivery_date
USPS
boolean Set to true to get the guaranteed delivery date for Express.
hazmat
USPSFedExUniUni
string Hazardous materials in the package.
USPSFedExPRIMARY_CONTAINED PRIMARY_PACKED PRIMARY SECONDARY_CONTAINED SECONDARY_PACKED SECONDARY ORMD LIMITED_QUANTITY
UniUniUN3481_LIBA UN3481_LICA UN3091_LMBA UN3091_LMCA
hazmat_code
OSMOneParcel
integer USPS hazardous-materials extra service code of the contents, from 810 to 832.
hub_id
UniUni
integer Pickup warehouse ID. Required. Values are in the hub sheet at docs.uniuni.com.
insurance_amount
USPS
float Declared value in USD to buy shipment insurance. Cannot be combined with carrier_insurance_amount.
is_return boolean Set to true to use the return service sub-type.
label_date string Ship date printed on the label, as YYYY-MM-DD or an ISO 8601 datetime with a time zone offset.
label_format string Label file format. Defaults to ZPL when the default label format at dashboard.vanlo.com/shipments is ZPL, and to PNG otherwise, as on a new account. A ZPL label cannot be converted later, such as into a PDF batch label.
ValuesPNG PDF ZPL EPL2
label_size string Label size in inches. 8.5X11 prints the same label with blank space around it, for sheet printers.
Values4X6default 8.5X11
machinable
USPS
boolean Set to false to mark the package non-machinable. Applies to First. Default true.
pickup_begin_time
DoorDashOnTrac
string When the package is ready for pickup.
DoorDashPrinted on the pickup instructions.
OnTracEarliest UTC time, such as 2026-07-28T20:00:00.
pickup_end_time
OnTrac
string UTC time the package leaves the origin. Defaults to label_date, or to now.
pickup_type
OnTrac
string How the package reaches OnTrac.
ValuesNonedefaultyou hand it over LaserShipOnTrac collects it
postage_label_inline boolean Set to true to get the label as base64 in label_file instead of a URL.
print_custom PrintCustom[] Custom text printed on the label. How many entries print depends on the carrier and service.
saturday_delivery
FedEx
boolean Set to true to request Saturday delivery.
smartpost_hub
FedEx
string SmartPost hub ID.
smartpost_manifest
FedEx
string Accepted and returned in options, but not sent to FedEx.
special_rates_eligibility
USPS
string Request restricted rates.
ValuesUSPS.MEDIAMAIL USPS.LIBRARYMAIL
total_value
UniUniDoorDashOnTrac
float Value of the contents in USD.
UniUniHelps with lost packages.
DoorDashPart of the price, so send it on every shipment.
OnTracThe declared value when carrier_insurance_amount is not set.

PrintCustom Object

Custom text on a label:

[
  {
    "name": "Order",
    "value": "1042"
  }
]
Parameter Type Specification
name string First part of text to print on label
value string Last part of text to print on label

DutyPayment Object

Send the duties payer inside options:

{
  "shipment": {
    "options": {
      "duty_payment": {
        "type": "BUYER"
      }
    }
  }
}

A payer that bills another carrier account carries that account beside type:

{
  "shipment": {
    "options": {
      "duty_payment": {
        "type": "THIRD_PARTY",
        "account": "123456789",
        "country": "US",
        "postal_code": "10001"
      }
    }
  }
}

duty_payment says who pays the duties and taxes on a FedEx or UPS shipment. Vanlo sends it to the carrier only when the origin and destination are in different duties areas, such as the United States and Canada. The United States, Puerto Rico, the US Virgin Islands and Guam are one area, though Guam needs a customs declaration. American Samoa and the Northern Mariana Islands are areas of their own.

Value Meaning Also send
SENDER The sender pays. Duties and taxes are billed to the carrier account that buys the label, which has to be your own account with the carrier. Nothing
BUYER The recipient pays the carrier on delivery. Nothing
RECEIVER The recipient's carrier account is billed. account
THIRD_PARTY A third-party carrier account is billed. account and country, and postal_code when the account has one

Rates

Get a Rate Quote

POST/api/v1/rate

curl -X POST https://www.vanlo.com/api/v1/rate \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "shipment": {
        "to_address": {
          "name": "John Doe",
          "street1": "148 W 51st St",
          "street2": "Apt 4B",
          "city": "New York",
          "state": "NY",
          "zip": "10019",
          "country": "US",
          "phone": "2125550199",
          "email": "john.doe@example.com",
          "residential": true
        },
        "from_address": {
          "name": "Jane Smith",
          "company": "Acme Goods",
          "street1": "417 Montgomery St",
          "street2": "Floor 5",
          "city": "San Francisco",
          "state": "CA",
          "zip": "94104",
          "country": "US",
          "phone": "4155550100",
          "email": "shipping@acme.example"
        },
        "parcel": {
          "length": 10.0,
          "width": 8.0,
          "height": 4.0,
          "weight": 32.0
        },
        "carrier_accounts": [
          "ca_..."
        ],
        "options": {
          "delivery_confirmation": "SIGNATURE"
        }
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Rate.create(
  to_address: {
    name: 'John Doe',
    street1: '148 W 51st St',
    street2: 'Apt 4B',
    city: 'New York',
    state: 'NY',
    zip: '10019',
    country: 'US',
    phone: '2125550199',
    email: 'john.doe@example.com',
    residential: true
  },
  from_address: {
    name: 'Jane Smith',
    company: 'Acme Goods',
    street1: '417 Montgomery St',
    street2: 'Floor 5',
    city: 'San Francisco',
    state: 'CA',
    zip: '94104',
    country: 'US',
    phone: '4155550100',
    email: 'shipping@acme.example'
  },
  parcel: {
    length: 10.0,
    width: 8.0,
    height: 4.0,
    weight: 32.0
  },
  carrier_accounts: ['ca_...'],
  options: {
    delivery_confirmation: 'SIGNATURE'
  }
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

rates = vanlo.Rate.create(
  to_address={
    "name": "John Doe",
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": True
  },
  from_address={
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example"
  },
  parcel={
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "weight": 32.0
  },
  carrier_accounts=["ca_..."],
  options={
    "delivery_confirmation": "SIGNATURE"
  }
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$rates = \Vanlo\Rate::create(array(
  'to_address' => array(
    'name' => 'John Doe',
    'street1' => '148 W 51st St',
    'street2' => 'Apt 4B',
    'city' => 'New York',
    'state' => 'NY',
    'zip' => '10019',
    'country' => 'US',
    'phone' => '2125550199',
    'email' => 'john.doe@example.com',
    'residential' => true
  ),
  'from_address' => array(
    'name' => 'Jane Smith',
    'company' => 'Acme Goods',
    'street1' => '417 Montgomery St',
    'street2' => 'Floor 5',
    'city' => 'San Francisco',
    'state' => 'CA',
    'zip' => '94104',
    'country' => 'US',
    'phone' => '4155550100',
    'email' => 'shipping@acme.example'
  ),
  'parcel' => array(
    'length' => 10.0,
    'width' => 8.0,
    'height' => 4.0,
    'weight' => 32.0
  ),
  'carrier_accounts' => array('ca_...'),
  'options' => array(
    'delivery_confirmation' => 'SIGNATURE'
  )
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

List<Rate> rates = Rate.Create(new Dictionary<string, object>() {
    { "to_address", new Dictionary<string, object>() {
        { "name", "John Doe" },
        { "street1", "148 W 51st St" },
        { "street2", "Apt 4B" },
        { "city", "New York" },
        { "state", "NY" },
        { "zip", "10019" },
        { "country", "US" },
        { "phone", "2125550199" },
        { "email", "john.doe@example.com" },
        { "residential", true }
    } },
    { "from_address", new Dictionary<string, object>() {
        { "name", "Jane Smith" },
        { "company", "Acme Goods" },
        { "street1", "417 Montgomery St" },
        { "street2", "Floor 5" },
        { "city", "San Francisco" },
        { "state", "CA" },
        { "zip", "94104" },
        { "country", "US" },
        { "phone", "4155550100" },
        { "email", "shipping@acme.example" }
    } },
    { "parcel", new Dictionary<string, object>() {
        { "length", 10.0 },
        { "width", 8.0 },
        { "height", 4.0 },
        { "weight", 32.0 }
    } },
    { "carrier_accounts", new List<string>() { "ca_..." } },
    { "options", new Dictionary<string, object>() {
        { "delivery_confirmation", "SIGNATURE" }
    } }
});

Quotes rates for a shipment without creating one. The parameters are nested under shipment, as on Create a Shipment.

Parameters

Parameter Type Specification
shipment[to_address]required Address Destination address (zip and country are required)
shipment[from_address]required Address Origin address (zip and country are required)
shipment[parcel]required Parcel Package dimensions and weight
shipment[customs_info] CustomsInfo Customs declaration, or the id of a saved one, for an international quote
shipment[carrier] string Filter rates to a specific carrier
shipment[carrier_accounts] string[] One or more Carrier Account ids to get rates from
shipment[options] Options Shipping options that may affect rates, such as special_rates_eligibility or hazmat. On an international quote, send the same duty_payment you will send on the shipment.

Returns

Response:

{
  "rates": [
    {
      "id": "",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": null,
      "created_at": null,
      "service": "GroundAdvantage",
      "delivery_date": "2026-10-26",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 6,
      "rate": "9.84",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DUXX0XXXXC08020",
        "quoted_service": "GroundAdvantage",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "12.47",
        "discount": "2.63",
        "discount_date": "2026-09-29",
        "total_freight": "9.84",
        "total_surcharges": "0.00",
        "services": {
          "DUXX0XXXXC08020": 12.47
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": null,
      "created_at": null,
      "service": "Priority",
      "delivery_date": "2026-10-23",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 3,
      "rate": "11.20",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DPXX0XXXXC08020",
        "quoted_service": "Priority",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "14.95",
        "discount": "3.75",
        "discount_date": "2026-09-29",
        "total_freight": "11.20",
        "total_surcharges": "0.00",
        "services": {
          "DPXX0XXXXC08020": 14.95
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": null,
      "created_at": null,
      "service": "Express",
      "delivery_date": "2026-10-22",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 2,
      "rate": "48.75",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DEXX0XXXXC08020",
        "quoted_service": "Express",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "52.30",
        "discount": "3.55",
        "discount_date": "2026-09-29",
        "total_freight": "48.75",
        "total_surcharges": "0.00",
        "services": {
          "DEXX0XXXXC08020": 52.3
        },
        "rdc": "04"
      },
      "usps_cubic": false
    }
  ]
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "to_address",
        "message": "is missing"
      }
    ]
  }
}

Response for INVALID_OPTIONS:

{
  "error": {
    "code": "INVALID_OPTIONS",
    "message": "Invalid options. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "options",
        "message": "delivery_confirmation must be one of: NO_SIGNATURE, SIGNATURE, ADULT_SIGNATURE, SIGNATURE_RESTRICTED, ADULT_SIGNATURE_RESTRICTED"
      }
    ]
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns an object with rates, an array of Rate. A quoted rate has an empty id and null shipment_id and created_at, so it cannot be bought: create a shipment to buy one.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A required field is missing or has the wrong shape, such as no to_address or a parcel without weight, or no carrier account matches carrier_accounts. error.errors names each field.
INVALID_OPTIONS 422 An options value is not allowed for the shipment, such as an unknown delivery_confirmation or a duty_payment with an unknown type.
NOT_FOUND 404 No carrier could rate the shipment. A carrier that cannot rate it is left out of the results, so this means none could.

Addresses

Address Object

An Address verified on creation:

{
  "id": "adr_...",
  "object": "Address",
  "created_at": "2026-10-20T15:04:11Z",
  "updated_at": "2026-10-20T15:04:11Z",
  "name": "Jane Smith",
  "company": "Acme Goods",
  "street1": "417 Montgomery St",
  "street2": "Floor 5",
  "city": "San Francisco",
  "state": "CA",
  "zip": "94104",
  "country": "US",
  "phone": "4155550100",
  "email": "shipping@acme.example",
  "residential": false,
  "verifications": {
    "delivery": {
      "success": true,
      "errors": [],
      "details": {
        "latitude": 37.79342,
        "longitude": -122.40288,
        "time_zone": "America/Los_Angeles"
      }
    },
    "verify": [
      "delivery"
    ]
  }
}

A postal address, used as a shipment's origin, destination, return or buyer address.

Parameter Type Specification
id string Unique identifier, begins with "adr_"
object string "Address"
name string Name of the person or contact
company string Company name associated with the address
street1 string First line of the street address
street2 string Second line of the street address
city string City
state string State or province (2-letter code for US, CA, AU)
zip string Zip or postal code
country string Two-letter ISO 3166 country code
phone string Phone number associated with the address
email string Email address
residential boolean Whether the address is a residential address
verifications object One { success, errors, details } result per check you asked for, keyed delivery or zip4, and verify listing the checks. Null when the address was not verified
created_at datetime When the address was created
updated_at datetime When the address was last updated

Create an Address

POST/api/v1/addresses

curl -X POST https://www.vanlo.com/api/v1/addresses \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "address": {
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": false
      },
      "verify": [
        "delivery"
      ]
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Address.create(
  name: 'Jane Smith',
  company: 'Acme Goods',
  street1: '417 Montgomery St',
  street2: 'Floor 5',
  city: 'San Francisco',
  state: 'CA',
  zip: '94104',
  country: 'US',
  phone: '4155550100',
  email: 'shipping@acme.example',
  residential: false,
  verify: ['delivery']
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

address = vanlo.Address.create(
  name="Jane Smith",
  company="Acme Goods",
  street1="417 Montgomery St",
  street2="Floor 5",
  city="San Francisco",
  state="CA",
  zip="94104",
  country="US",
  phone="4155550100",
  email="shipping@acme.example",
  residential=False,
  verify=["delivery"]
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$address = \Vanlo\Address::create(array(
  'name' => 'Jane Smith',
  'company' => 'Acme Goods',
  'street1' => '417 Montgomery St',
  'street2' => 'Floor 5',
  'city' => 'San Francisco',
  'state' => 'CA',
  'zip' => '94104',
  'country' => 'US',
  'phone' => '4155550100',
  'email' => 'shipping@acme.example',
  'residential' => false,
  'verify' => array('delivery')
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Address address = Address.Create(new Dictionary<string, object>() {
    { "name", "Jane Smith" },
    { "company", "Acme Goods" },
    { "street1", "417 Montgomery St" },
    { "street2", "Floor 5" },
    { "city", "San Francisco" },
    { "state", "CA" },
    { "zip", "94104" },
    { "country", "US" },
    { "phone", "4155550100" },
    { "email", "shipping@acme.example" },
    { "residential", false },
    { "verify", new List<string>() { "delivery" } }
});

Creates an address, and verifies it when verify or verify_strict is sent. The fields go inside address; verify and verify_strict sit beside it.

Parameters

Parameter Type Specification
name string Name of the person or contact
company string Company name associated with the address
street1 string First line of the street address
street2 string Second line of the street address
city string City
state string State or province (2-letter code for US, CA, AU)
zip string Zip or postal code
country string Two-letter ISO 3166 country code
phone string Phone number
email string Email address
residential boolean Whether the address is residential
verify string[] Set to ["delivery"], or ["delivery", "zip4"] for a US address, to verify the address on creation. The address is saved even when it cannot be verified, with the problems in verifications.
verify_strict string[] Takes the same values as verify, but requires a clean verification. An address that cannot be verified is not saved.

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "zip",
        "message": "Invalid ZIP code format. US ZIP codes must be 5 digits (e.g., 90210) or 5+4 format (e.g., 90210-1234)."
      }
    ]
  }
}

Response for CARRIER_REJECTED_ADDRESS:

{
  "error": {
    "code": "CARRIER_REJECTED_ADDRESS",
    "message": "The address could not be verified. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "address",
        "message": "Address not found"
      },
      {
        "field": "street1",
        "message": "House number is missing"
      }
    ]
  }
}

Response for PROVIDER_503:

{
  "error": {
    "code": "PROVIDER_503",
    "message": "No response from service provider, please try again or contact support. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Address, with the results in verifications when verification was requested.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A field is missing or invalid, or the verification provider rejected the request. error.errors names each field.
CARRIER_REJECTED_ADDRESS 422 With verify_strict, the address could not be verified. error.errors lists the problems.
PROVIDER_503 503 The address verification provider did not respond.

Retrieve an Address

GET/api/v1/addresses/:id

curl https://www.vanlo.com/api/v1/addresses/adr_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Address.retrieve('adr_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Address.retrieve('adr_...')
require_once("/path/to/lib/vanlo.php");
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

\Vanlo\Address::retrieve('adr_...');
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Address address = Address.Retrieve("adr_...");

Retrieves an address by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the address

Returns

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Address.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No address of yours has this id.

Parcels

Parcel Object

A Parcel:

{
  "id": "prcl_...",
  "object": "Parcel",
  "created_at": "2026-10-20T15:04:11Z",
  "updated_at": "2026-10-20T15:04:11Z",
  "length": 10.0,
  "width": 8.0,
  "height": 4.0,
  "predefined_package": null,
  "weight": 32.0
}

The dimensions and weight of one package. Send a predefined_package when shipping in carrier-supplied packaging.

Parameter Type Specification
id string Unique identifier, begins with "prcl_"
object string "Parcel"
length float Length of the parcel in inches
width float Width of the parcel in inches
height float Height of the parcel in inches
weight float Weight of the parcel in ounces
predefined_package string Carrier predefined package type, if applicable
created_at datetime When the parcel was created
updated_at datetime When the parcel was last updated

Create a Parcel

POST/api/v1/parcels

curl -X POST https://www.vanlo.com/api/v1/parcels \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "parcel": {
        "length": 10.0,
        "width": 8.0,
        "height": 4.0,
        "weight": 32.0
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Parcel.create(
  length: 10.0,
  width: 8.0,
  height: 4.0,
  weight: 32.0
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

parcel = vanlo.Parcel.create(
  length=10.0,
  width=8.0,
  height=4.0,
  weight=32.0
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$parcel = \Vanlo\Parcel::create(array(
  'length' => 10.0,
  'width' => 8.0,
  'height' => 4.0,
  'weight' => 32.0
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Parcel parcel = Parcel.Create(new Dictionary<string, object>() {
    { "length", 10.0 },
    { "width", 8.0 },
    { "height", 4.0 },
    { "weight", 32.0 }
});

Creates a parcel. Its id can stand in for the parcel on any later shipment.

Parameters

Parameter Type Specification
length float Length of the parcel in inches
width float Width of the parcel in inches
height float Height of the parcel in inches
weight float Weight of the parcel in ounces
predefined_package string Carrier predefined package type
Predefined package types by carrier

Package Type Description
Card Postcard or greeting card
Letter Standard letter envelope
Flat Large envelope or flat
SoftPack Padded or poly mailer
Parcel Standard parcel
LargeParcel Large parcel (over 1 cubic foot)
IrregularParcel Non-rectangular parcel
FlatRateEnvelope USPS Flat Rate Envelope
FlatRateLegalEnvelope USPS Flat Rate Legal Envelope
FlatRatePaddedEnvelope USPS Flat Rate Padded Envelope
FlatRateGiftCardEnvelope USPS Flat Rate Gift Card Envelope
FlatRateWindowEnvelope USPS Flat Rate Window Envelope
FlatRateCardboardEnvelope USPS Flat Rate Cardboard Envelope
SmallFlatRateEnvelope USPS Small Flat Rate Envelope
SmallFlatRateBox USPS Small Flat Rate Box
MediumFlatRateBox USPS Medium Flat Rate Box
LargeFlatRateBox USPS Large Flat Rate Box
LargeFlatRateBoxAPOFPO USPS Large Flat Rate Box (APO/FPO/DPO)
RegionalRateBoxA USPS Regional Rate Box A
RegionalRateBoxB USPS Regional Rate Box B
Package Type Description
FedExEnvelope FedEx Envelope
FedExBox FedEx Box
FedExPak FedEx Pak
FedExTube FedEx Tube
FedEx10kgBox FedEx 10kg Box
FedEx25kgBox FedEx 25kg Box
FedExSmallBox FedEx Small Box
FedExMediumBox FedEx Medium Box
FedExLargeBox FedEx Large Box
FedExExtraLargeBox FedEx Extra Large Box
Package Type Description
UPSLetter UPS Letter
Tube UPS Tube
Pak UPS Pak
UPSExpressBox UPS Express Box
SmallExpressBox UPS Small Express Box
MediumExpressBox UPS Medium Express Box
LargeExpressBox UPS Large Express Box
UPS10kgBox UPS 10kg Box
UPS25kgBox UPS 25kg Box
Pallet Pallet
BPMParcel Bound Printed Matter Parcel
BPMFlat Bound Printed Matter Flat
Flat Flat

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "weight",
        "message": "Package weight must be greater than 0. Please enter a valid weight."
      }
    ]
  }
}

Returns the Parcel.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A field is missing or invalid, such as no weight or a weight of 0. error.errors names each field.

Retrieve a Parcel

GET/api/v1/parcels/:id

curl https://www.vanlo.com/api/v1/parcels/prcl_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Parcel.retrieve("prcl_...")
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Parcel.retrieve("prcl_...")
require_once("/path/to/lib/vanlo.php");
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

\Vanlo\Parcel::retrieve("prcl_...");
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Parcel parcel = Parcel.Retrieve("prcl_...");

Retrieves a parcel by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the parcel

Returns

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Parcel.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No parcel of yours has this id.

CustomsInfos

CustomsInfo Object

A CustomsInfo:

{
  "id": "cstinfo_...",
  "object": "CustomsInfo",
  "created_at": "2026-10-20T15:04:11Z",
  "updated_at": "2026-10-20T15:04:11Z",
  "contents_type": "merchandise",
  "contents_explanation": null,
  "customs_certify": true,
  "customs_signer": "Jane Smith",
  "eel_pfc": "NOEEI 30.37(a)",
  "non_delivery_option": "return",
  "restriction_comments": null,
  "restriction_type": "none",
  "customs_items": [
    {
      "description": "Cotton T-shirt",
      "quantity": 2,
      "value": 30.0,
      "weight": 12.0,
      "currency": "USD",
      "hs_tariff_number": "610910",
      "code": "TSHIRT-M-BLU",
      "origin_country": "US"
    },
    {
      "description": "Ceramic mug",
      "quantity": 1,
      "value": 14.0,
      "weight": 18.0,
      "currency": "USD",
      "hs_tariff_number": "691200",
      "code": "MUG-11OZ",
      "origin_country": "CN"
    }
  ]
}

The customs declaration for an international shipment, or one to an APO/FPO/DPO address, with a CustomsItem for each kind of goods.

Parameter Type Specification
id string Unique identifier, begins with "cstinfo_"
object string "CustomsInfo"
contents_type string Type of item being shipped: "documents", "gift", "merchandise", "returned_goods", "sample", or "other"
contents_explanation string Human-readable description of content, required if contents_type is "other"
customs_certify boolean Whether the customs form has been signed by the customs_signer
customs_signer string Name of the person signing the customs form
eel_pfc string Electronic Export License or PFC number. For items valued under $2,500 use "NOEEI 30.37(a)"
non_delivery_option string Action to take if the package cannot be delivered: "abandon" or "return" (default)
restriction_comments string Additional comments for restricted shipments, required if restriction_type is "other"
restriction_type string Type of restriction: "none", "other", "quarantine", or "sanitary_phytosanitary_inspection"
customs_items CustomsItem[] Array of CustomsItem objects describing the contents
created_at datetime When the customs info was created
updated_at datetime When the customs info was last updated

Create a CustomsInfo

POST/api/v1/customs_infos

curl -X POST https://www.vanlo.com/api/v1/customs_infos \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "customs_info": {
        "contents_type": "merchandise",
        "customs_certify": true,
        "customs_signer": "Jane Smith",
        "eel_pfc": "NOEEI 30.37(a)",
        "non_delivery_option": "return",
        "restriction_type": "none",
        "customs_items": [
          {
            "description": "Cotton T-shirt",
            "quantity": 2,
            "value": 30.0,
            "weight": 12.0,
            "currency": "USD",
            "hs_tariff_number": "610910",
            "code": "TSHIRT-M-BLU",
            "origin_country": "US"
          },
          {
            "description": "Ceramic mug",
            "quantity": 1,
            "value": 14.0,
            "weight": 18.0,
            "currency": "USD",
            "hs_tariff_number": "691200",
            "code": "MUG-11OZ",
            "origin_country": "CN"
          }
        ]
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::CustomsInfo.create(
  contents_type: 'merchandise',
  customs_certify: true,
  customs_signer: 'Jane Smith',
  eel_pfc: 'NOEEI 30.37(a)',
  non_delivery_option: 'return',
  restriction_type: 'none',
  customs_items: [
    {
      description: 'Cotton T-shirt',
      quantity: 2,
      value: 30.0,
      weight: 12.0,
      currency: 'USD',
      hs_tariff_number: '610910',
      code: 'TSHIRT-M-BLU',
      origin_country: 'US'
    },
    {
      description: 'Ceramic mug',
      quantity: 1,
      value: 14.0,
      weight: 18.0,
      currency: 'USD',
      hs_tariff_number: '691200',
      code: 'MUG-11OZ',
      origin_country: 'CN'
    }
  ]
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

customs_info = vanlo.CustomsInfo.create(
  contents_type="merchandise",
  customs_certify=True,
  customs_signer="Jane Smith",
  eel_pfc="NOEEI 30.37(a)",
  non_delivery_option="return",
  restriction_type="none",
  customs_items=[
    {
      "description": "Cotton T-shirt",
      "quantity": 2,
      "value": 30.0,
      "weight": 12.0,
      "currency": "USD",
      "hs_tariff_number": "610910",
      "code": "TSHIRT-M-BLU",
      "origin_country": "US"
    },
    {
      "description": "Ceramic mug",
      "quantity": 1,
      "value": 14.0,
      "weight": 18.0,
      "currency": "USD",
      "hs_tariff_number": "691200",
      "code": "MUG-11OZ",
      "origin_country": "CN"
    }
  ]
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$customs_info = \Vanlo\CustomsInfo::create(array(
  'contents_type' => 'merchandise',
  'customs_certify' => true,
  'customs_signer' => 'Jane Smith',
  'eel_pfc' => 'NOEEI 30.37(a)',
  'non_delivery_option' => 'return',
  'restriction_type' => 'none',
  'customs_items' => array(
    array(
      'description' => 'Cotton T-shirt',
      'quantity' => 2,
      'value' => 30.0,
      'weight' => 12.0,
      'currency' => 'USD',
      'hs_tariff_number' => '610910',
      'code' => 'TSHIRT-M-BLU',
      'origin_country' => 'US'
    ),
    array(
      'description' => 'Ceramic mug',
      'quantity' => 1,
      'value' => 14.0,
      'weight' => 18.0,
      'currency' => 'USD',
      'hs_tariff_number' => '691200',
      'code' => 'MUG-11OZ',
      'origin_country' => 'CN'
    )
  )
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

CustomsInfo customsInfo = CustomsInfo.Create(new Dictionary<string, object>() {
    { "contents_type", "merchandise" },
    { "customs_certify", true },
    { "customs_signer", "Jane Smith" },
    { "eel_pfc", "NOEEI 30.37(a)" },
    { "non_delivery_option", "return" },
    { "restriction_type", "none" },
    { "customs_items", new List<Dictionary<string, object>>() {
        new Dictionary<string, object>() {
            { "description", "Cotton T-shirt" },
            { "quantity", 2 },
            { "value", 30.0 },
            { "weight", 12.0 },
            { "currency", "USD" },
            { "hs_tariff_number", "610910" },
            { "code", "TSHIRT-M-BLU" },
            { "origin_country", "US" }
        },
        new Dictionary<string, object>() {
            { "description", "Ceramic mug" },
            { "quantity", 1 },
            { "value", 14.0 },
            { "weight", 18.0 },
            { "currency", "USD" },
            { "hs_tariff_number", "691200" },
            { "code", "MUG-11OZ" },
            { "origin_country", "CN" }
        }
    } }
});

Creates a customs declaration. Its id can stand in for customs_info on any later shipment.

Parameters

Parameter Type Specification
eel_pfc string Electronic Export License or PFC number. For items valued under $2,500 use "NOEEI 30.37(a)"
contents_type string "documents", "gift", "merchandise", "returned_goods", "sample", or "other"
contents_explanation string Description of goods, required when contents_type is "other"
customs_certify boolean Whether the customs form has been signed
customs_signer string Name of the person signing the customs form
restriction_type string "none", "other", "quarantine", or "sanitary_phytosanitary_inspection"
restriction_comments string Additional comments, required when restriction_type is "other"
non_delivery_option string "abandon" or "return" (default)
customs_items CustomsItem[] Array of CustomsItem objects describing the contents

Returns

Response for PARAMETER.REQUIRED:

{
  "error": {
    "code": "PARAMETER.REQUIRED",
    "message": "Missing required parameter: customs_items. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid parameters were passed and the record could not be persisted. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "contents_type",
        "message": "is not included in the list"
      }
    ]
  }
}

Returns the CustomsInfo.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
PARAMETER.REQUIRED 422 customs_items is missing.
BAD_REQUEST 400 A value cannot be saved, such as an unknown contents_type. error.errors names each field.

Nested Objects

Objects a CustomsInfo carries. Each one also expands in place wherever a table names it.

CustomsItem Object

A CustomsItem:

{
  "description": "Cotton T-shirt",
  "quantity": 2,
  "value": 30.0,
  "weight": 12.0,
  "currency": "USD",
  "hs_tariff_number": "610910",
  "code": "TSHIRT-M-BLU",
  "origin_country": "US"
}
Parameter Type Specification
description string Human-readable description of the item. Required
hs_tariff_number string Harmonized System tariff code for the item, 6 to 15 letters and digits. Separators such as dots are ignored. A UPS international shipment requires it on every item
origin_country string Two-letter ISO 3166 country code of the item's origin. Defaults to "US"
quantity integer Number of items. Required
value float Total value of the items, in currency. Required
weight float Total weight of the items in ounces. Required
currency string Three-letter currency code of value. Defaults to "USD"
code string Your SKU or product code for the item

Batches

Batch Object

A purchased Batch with its combined label and scan form:

{
  "id": "batch_...",
  "object": "Batch",
  "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../batch_labels.pdf",
  "num_shipments": 2,
  "state": "label_generated",
  "scan_form": {
    "id": "sf_...",
    "object": "ScanForm",
    "tracking_codes": [
      "9405500106024190341287",
      "9405500106024190341294"
    ],
    "address": {
      "id": "adr_...",
      "object": "Address",
      "created_at": "2026-10-20T15:04:11Z",
      "updated_at": "2026-10-20T15:04:11Z",
      "name": "Jane Smith",
      "company": "Acme Goods",
      "street1": "417 Montgomery St",
      "street2": "Floor 5",
      "city": "San Francisco",
      "state": "CA",
      "zip": "94104",
      "country": "US",
      "phone": "4155550100",
      "email": "shipping@acme.example",
      "residential": null,
      "verifications": null
    },
    "message": null,
    "batch_id": "batch_...",
    "form": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp...",
    "reference": null,
    "status": "ready",
    "form_url": "https://www.vanlo.com/rails/active_storage/blobs/proxy/.../scan_form.pdf",
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z"
  },
  "shipments": [
    {
      "id": "shp_...",
      "batch_status": "postage_purchased",
      "batch_message": null,
      "tracking_code": "9405500106024190341287"
    },
    {
      "id": "shp_...",
      "batch_status": "postage_purchased",
      "batch_message": null,
      "tracking_code": "9405500106024190341294"
    }
  ],
  "status": {
    "created": 0,
    "queued_for_purchase": 0,
    "creation_failed": 0,
    "postage_purchased": 2,
    "postage_purchase_failed": 0
  },
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z"
}

A group of shipments bought, labelled and scanned together. Each step runs in the background and sends a webhook Event when it finishes.

Parameter Type Specification
id string Unique identifier, begins with "batch_"
object string "Batch"
state string Current state of the batch: "creating", "created", "purchasing", "purchased", "purchase_failed", "label_generating", or "label_generated"
status BatchStatus Counts of shipments in each processing state
num_shipments integer Total number of shipments in the batch
scan_form ScanForm The associated ScanForm object, if generated
shipments BatchShipment[] Array of BatchShipment objects with per-shipment status
label_url string URL of the combined label file, once generated
created_at datetime When the batch was created
updated_at datetime When the batch was last updated

Create a Batch

POST/api/v1/batches

curl -X POST https://www.vanlo.com/api/v1/batches \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "batch": {
        "shipments": [
          {
            "id": "shp_..."
          },
          {
            "id": "shp_...",
            "carrier": "USPS",
            "service": "GroundAdvantage"
          }
        ]
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

batch = Vanlo::Batch.create(
  shipments: [
    {
      id: 'shp_...'
    },
    {
      id: 'shp_...',
      carrier: 'USPS',
      service: 'GroundAdvantage'
    }
  ]
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

batch = vanlo.Batch.create(
  shipments=[
    {
      "id": "shp_..."
    },
    {
      "id": "shp_...",
      "carrier": "USPS",
      "service": "GroundAdvantage"
    }
  ]
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$batch = \Vanlo\Batch::create(array(
  'shipments' => array(
    array(
      'id' => 'shp_...'
    ),
    array(
      'id' => 'shp_...',
      'carrier' => 'USPS',
      'service' => 'GroundAdvantage'
    )
  )
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Batch batch = Batch.Create(new Dictionary<string, object>() {
    { "shipments", new List<Dictionary<string, object>>() {
        new Dictionary<string, object>() {
            { "id", "shp_..." }
        },
        new Dictionary<string, object>() {
            { "id", "shp_..." },
            { "carrier", "USPS" },
            { "service", "GroundAdvantage" }
        }
    } }
});

Creates a batch from shipments you already created, sent by id. A webhook Event is sent once its state is created.

Parameters

Parameter Type Specification
shipments object[] 1 to 100 shipments, each as { "id": "shp_..." }. An entry may add carrier and service to change the rate it is bought at

Returns

Response for PARAMETER.REQUIRED:

{
  "error": {
    "code": "PARAMETER.REQUIRED",
    "message": "Missing required parameter: shipments. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "id",
        "message": "is missing"
      }
    ]
  }
}

Response for UNPROCESSABLE_ENTITY:

{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "One or more shipments is required to perform this action. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Batch in state created, or purchased when every shipment already has a label.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
PARAMETER.REQUIRED 422 shipments is missing.
BAD_REQUEST 400 A shipment entry has no id, or there are more than 100. error.errors names each field.
UNPROCESSABLE_ENTITY 422 None of the ids is a shipment of yours, or the batch could not be created. error.message says why.

Buy a Batch

POST/api/v1/batches/:id/buy

curl -X POST https://www.vanlo.com/api/v1/batches/batch_.../buy \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

batch = Vanlo::Batch.retrieve('batch_...')
batch.buy
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

batch = vanlo.Batch.retrieve('batch_...')
batch.buy()
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$batch = \Vanlo\Batch::retrieve('batch_...');
$batch->buy();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Batch batch = Batch.Retrieve("batch_...");
batch.Buy();

Buys a label for every shipment in a batch, in the background. The batch must be in the created state, and a webhook Event is sent when every shipment has been processed.

Parameters

Parameter Type Specification
id string Unique identifier of the batch to purchase

Returns

Response for UNPROCESSABLE_ENTITY:

{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "This batch is either already purchased or currently being purchased. If purchasing fails please try again at a later time. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Batch in the purchasing state.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
UNPROCESSABLE_ENTITY 422 The batch is already purchased or being purchased, or one of its shipments failed to be created.
NOT_FOUND 404 No batch of yours has this id.

Create Batch Labels

POST/api/v1/batches/:id/label

curl -X POST https://www.vanlo.com/api/v1/batches/batch_.../label \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "file_format": "zpl"
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

batch = Vanlo::Batch.retrieve('batch_...')
batch.label(file_format: 'zpl')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

batch = vanlo.Batch.retrieve('batch_...')
batch.label(file_format = 'zpl')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$batch = \Vanlo\Batch::retrieve('batch_...');
$batch->label(array('file_format' => 'zpl'));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Batch batch = Batch.Retrieve("batch_...");

batch.GenerateLabel("zpl");

Combines the labels of every shipment in a bought batch into one file, in the background. A webhook Event is sent when label_url is ready.

Parameters

Parameter Type Specification
file_format string Combined file format: "pdf", "zpl", or "zip"

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "One or more of the shipments don't have postage associated to them. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Batch; label_url is filled in once the file is ready.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A shipment in the batch has no label yet, or file_format is missing or not one of the listed values.
NOT_FOUND 404 No batch of yours has this id.

Create a Batch ScanForm

POST/api/v1/batches/:id/scan_form

curl -X POST https://www.vanlo.com/api/v1/batches/batch_.../scan_form \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

batch = Vanlo::Batch.retrieve('batch_...')
batch.create_scan_form
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

batch = vanlo.Batch.retrieve('batch_...')
batch.create_scan_form()
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$batch = \Vanlo\Batch::retrieve('batch_...');
$batch->create_scan_form();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Batch batch = Batch.Retrieve("batch_...");

batch.GenerateScanForm();

Creates a ScanForm for every shipment in a bought batch.

Parameters

This call takes no parameters.

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "One or more of the shipments don't have postage associated to them. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for LOCKED:

{
  "error": {
    "code": "LOCKED",
    "message": "Another resource is creating at the moment. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Batch with its scan_form.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A shipment in the batch has no label yet, or a shipment cannot go on a scan form, such as one already on another. error.details lists the scan-form ids involved.
LOCKED 429 A scan form for this batch is already being created.
NOT_FOUND 404 No batch of yours has this id.

Retrieve a Batch

GET/api/v1/batches/:id

curl https://www.vanlo.com/api/v1/batches/batch_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Batch.retrieve('batch_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Batch.retrieve('batch_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$batch = \Vanlo\Batch::retrieve('batch_...');
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Batch batch = Batch.Retrieve("batch_...");

Retrieves a batch by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the batch

Returns

Response:

{
  "id": "batch_...",
  "object": "Batch",
  "label_url": null,
  "num_shipments": 2,
  "state": "purchased",
  "scan_form": null,
  "shipments": [
    {
      "id": "shp_...",
      "batch_status": "postage_purchased",
      "batch_message": null,
      "tracking_code": "9405500106024190341287"
    },
    {
      "id": "shp_...",
      "batch_status": "postage_purchased",
      "batch_message": null,
      "tracking_code": "9405500106024190341294"
    }
  ],
  "status": {
    "created": 0,
    "queued_for_purchase": 0,
    "creation_failed": 0,
    "postage_purchased": 2,
    "postage_purchase_failed": 0
  },
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z"
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Batch.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No batch of yours has this id.

Nested Objects

Objects a Batch carries. Each one also expands in place wherever a table names it.

BatchStatus Object

A BatchStatus:

{
  "created": 0,
  "queued_for_purchase": 0,
  "creation_failed": 0,
  "postage_purchased": 2,
  "postage_purchase_failed": 0
}
Parameter Type Specification
created integer Number of shipments that have been created but not yet queued
queued_for_purchase integer Number of shipments queued for postage purchase
creation_failed integer Number of shipments that failed to be created
postage_purchased integer Number of shipments with postage successfully purchased
postage_purchase_failed integer Number of shipments where postage purchase failed

BatchShipment Object

A BatchShipment:

{
  "id": "shp_...",
  "batch_status": "postage_purchased",
  "batch_message": null,
  "tracking_code": "9405500106024190341287"
}
Parameter Type Specification
id string Unique identifier of the shipment, begins with "shp_"
batch_status string Status of the shipment within the batch: "created", "queued_for_purchase", "postage_purchased", or "postage_purchase_failed"
batch_message string Error message if the shipment failed during batch processing
tracking_code string Tracking code for the shipment, if purchased

ScanForms

ScanForm Object

A ScanForm:

{
  "id": "sf_...",
  "object": "ScanForm",
  "tracking_codes": [
    "9405500106024190341287",
    "9405500106024190341294"
  ],
  "address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "message": null,
  "batch_id": null,
  "form": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp...",
  "reference": "order-1042",
  "status": "ready",
  "form_url": "https://www.vanlo.com/rails/active_storage/blobs/proxy/.../scan_form.pdf",
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-20T15:06:40Z"
}

A carrier manifest that lets the carrier scan many packages with one barcode at pickup.

Parameter Type Specification
id string Unique identifier, begins with "sf_"
object string "ScanForm"
tracking_codes string[] Array of tracking codes included in the scan form
address Address The Address that the scan form applies to
status string Current status of the scan form: "pending", "ready", or "failed"
message string Error message if the scan form failed to generate
warnings object Shipments left off a ready scan form: each shipment id maps to a list of the reasons. Present only when there are some
form_url string URL of the scan form PDF document
form string Base64-encoded scan form document, if available
batch_id string Identifier of the associated Batch, begins with "batch_"
reference string Arbitrary reference string for the scan form
created_at datetime When the scan form was created
updated_at datetime When the scan form was last updated

Create a ScanForm

POST/api/v1/scan_forms

curl -X POST https://www.vanlo.com/api/v1/scan_forms \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "shipments": [
        {
          "id": "shp_..."
        },
        {
          "id": "shp_..."
        }
      ],
      "carrier": "USPS"
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

scan_form = Vanlo::ScanForm.create(
  shipments: [
    {
      id: 'shp_...'
    },
    {
      id: 'shp_...'
    }
  ],
  carrier: 'USPS'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

scan_form = vanlo.ScanForm.create(
  shipments=[
    {
      "id": "shp_..."
    },
    {
      "id": "shp_..."
    }
  ],
  carrier="USPS"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$scan_form = \Vanlo\ScanForm::create(array(
  'shipments' => array(
    array(
      'id' => 'shp_...'
    ),
    array(
      'id' => 'shp_...'
    )
  ),
  'carrier' => 'USPS'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

ScanForm scanForm = ScanForm.Create(new Dictionary<string, object>() {
    { "shipments", new List<Dictionary<string, object>>() {
        new Dictionary<string, object>() {
            { "id", "shp_..." }
        },
        new Dictionary<string, object>() {
            { "id", "shp_..." }
        }
    } },
    { "carrier", "USPS" }
});

Creates a scan form for one or more purchased shipments, named by id or by reference. To scan a whole batch, use Create a Batch ScanForm.

Parameters

Parameter Type Specification
shipments object[] The shipments to include, each as { "id": "shp_..." }
reference string Instead of shipments, include today's shipments with this reference, or * for all of today's shipments. Shipments already on a scan form are left out
up_to_time datetime With reference, only include shipments created before this time. Defaults to now
carrier string USPS, the default. Scan forms are not available for other carriers

Returns

Response for PARAMETER.REQUIRED:

{
  "error": {
    "code": "PARAMETER.REQUIRED",
    "message": "Missing required parameter: shipments. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "All shipments on a Scan Form must ship from the same warehouse address. Please select shipments from a single location. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "ScanForm",
        "message": "All shipments on a Scan Form must ship from the same warehouse address. Please select shipments from a single location."
      }
    ],
    "details": {
      "from_address_ids": [
        "adr_...",
        "adr_..."
      ]
    }
  }
}

Response for LOCKED:

{
  "error": {
    "code": "LOCKED",
    "message": "Another resource is creating at the moment. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the ScanForm.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
PARAMETER.REQUIRED 422 Neither shipments nor reference is sent.
BAD_REQUEST 400 No shipment is eligible, the shipments cannot share a scan form, such as ones from different origin addresses, or the carrier has no scan forms. error.details holds any ids involved.
LOCKED 429 A scan form is already being created for these shipments.

Create a ScanForm for All Eligible Shipments

POST/api/v1/scan_forms/all

curl -X POST https://www.vanlo.com/api/v1/scan_forms/all \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "reference": "*",
      "up_to_time": "2026-10-20T17:00:00-04:00",
      "carrier": "USPS"
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

scan_form = Vanlo::ScanForm.create_all(
  reference: '*',
  up_to_time: '2026-10-20T17:00:00-04:00',
  carrier: 'USPS'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

scan_form = vanlo.ScanForm.create_all(
  reference="*",
  up_to_time="2026-10-20T17:00:00-04:00",
  carrier="USPS"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$scan_form = \Vanlo\ScanForm::create_all(array(
  'reference' => '*',
  'up_to_time' => '2026-10-20T17:00:00-04:00',
  'carrier' => 'USPS'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

ScanForm scanForm = ScanForm.CreateAll(new Dictionary<string, object>() {
    { "reference", "*" },
    { "up_to_time", "2026-10-20T17:00:00-04:00" },
    { "carrier", "USPS" }
});

The same call as Create a ScanForm at another path. Send reference as * to include every shipment created today that is not yet on a scan form.

Parameters

Parameter Type Specification
reference string A shipment reference to include today's shipments with it, or * for all of them
up_to_time datetime Only include shipments created before this time. Defaults to now
carrier string USPS, the default. Scan forms are not available for other carriers
shipments object[] Shipments by id, as on Create a ScanForm

Returns

Response for PARAMETER.REQUIRED:

{
  "error": {
    "code": "PARAMETER.REQUIRED",
    "message": "Missing required parameter: shipments. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "All shipments on a Scan Form must ship from the same warehouse address. Please select shipments from a single location. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "ScanForm",
        "message": "All shipments on a Scan Form must ship from the same warehouse address. Please select shipments from a single location."
      }
    ],
    "details": {
      "from_address_ids": [
        "adr_...",
        "adr_..."
      ]
    }
  }
}

Response for LOCKED:

{
  "error": {
    "code": "LOCKED",
    "message": "Another resource is creating at the moment. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the ScanForm.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
PARAMETER.REQUIRED 422 Neither shipments nor reference is sent.
BAD_REQUEST 400 No shipment is eligible, the shipments cannot share a scan form, such as ones from different origin addresses, or the carrier has no scan forms. error.details holds any ids involved.
LOCKED 429 A scan form is already being created for these shipments.

List ScanForms

GET/api/v1/scan_forms

curl -G https://www.vanlo.com/api/v1/scan_forms \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -d 'page_size=2' \
  -d 'reference=order-1042'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::ScanForm.all(
  page_size: 2,
  reference: 'order-1042'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.ScanForm.all(
  page_size=2,
  reference="order-1042"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$scan_forms = \Vanlo\ScanForm::all(array(
  'page_size' => 2,
  'reference' => 'order-1042'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

ScanFormList scanFormList = ScanForm.List(new Dictionary<string, object>() {
    { "page_size", 2 },
    { "reference", "order-1042" }
});

Lists your scan forms a page at a time. Pass before_id or after_id to say where the next page begins.

Parameters

Parameter Type Specification
before_id string Return scan forms created before this id
after_id string Return scan forms created after this id
start_datetime datetime Only return scan forms created after this timestamp
end_datetime datetime Only return scan forms created before this timestamp
page_size integer Number of scan forms to return per page (default 20, max 100)
reference string Only return scan forms with this reference

Returns

Response:

{
  "scan_forms": [
    {
      "id": "sf_...",
      "object": "ScanForm",
      "tracking_codes": [
        "9405500106024190341287"
      ],
      "address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "message": null,
      "warnings": {
        "shp_...": [
          "This shipment is already in_transit and cannot be added to a Scan Form."
        ]
      },
      "batch_id": null,
      "form": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp...",
      "reference": "order-1042",
      "status": "ready",
      "form_url": "https://www.vanlo.com/rails/active_storage/blobs/proxy/.../scan_form.pdf",
      "created_at": "2026-10-20T15:06:40Z",
      "updated_at": "2026-10-20T15:06:40Z"
    },
    {
      "id": "sf_...",
      "object": "ScanForm",
      "tracking_codes": [
        "9405500106024190327715"
      ],
      "address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "message": null,
      "batch_id": null,
      "form": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp...",
      "reference": "order-1042",
      "status": "ready",
      "form_url": "https://www.vanlo.com/rails/active_storage/blobs/proxy/.../scan_form.pdf",
      "created_at": "2026-10-19T21:10:05Z",
      "updated_at": "2026-10-19T21:10:05Z"
    }
  ],
  "has_more": true
}

Returns an object with scan_forms, an array of ScanForm, and has_more, which says whether another page exists.

On failure it returns one of the common errors; this call has none of its own.

Retrieve a ScanForm

GET/api/v1/scan_forms/:id

curl https://www.vanlo.com/api/v1/scan_forms/sf_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::ScanForm.retrieve('sf_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.ScanForm.retrieve('sf_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$scan_form = \Vanlo\ScanForm::retrieve('sf_...')
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

ScanForm otherScanForm = ScanForm.Retrieve("sf_...");

Retrieves a scan form by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the scan form

Returns

Response:

{
  "id": "sf_...",
  "object": "ScanForm",
  "tracking_codes": [
    "9405500106024190341287",
    "9405500106024190341294"
  ],
  "address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "message": null,
  "batch_id": null,
  "form": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp...",
  "reference": "order-1042",
  "status": "ready",
  "form_url": "https://www.vanlo.com/rails/active_storage/blobs/proxy/.../scan_form.pdf",
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-20T15:06:40Z"
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the ScanForm.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No scan form of yours has this id.

Orders

Order Object

A purchased Order:

{
  "id": "order_...",
  "object": "Order",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "shipments": [
    {
      "id": "shp_...",
      "object": "Shipment",
      "created_at": "2026-10-20T15:04:12Z",
      "updated_at": "2026-10-20T15:06:40Z",
      "reference": "order-1042-1",
      "usps_zone": "08",
      "custom_id": "order-1042-1",
      "from_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "to_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "John Doe",
        "company": null,
        "street1": "148 W 51st St",
        "street2": "Apt 4B",
        "city": "New York",
        "state": "NY",
        "zip": "10019",
        "country": "US",
        "phone": "2125550199",
        "email": "john.doe@example.com",
        "residential": true,
        "verifications": null
      },
      "return_address": null,
      "buyer_address": null,
      "parcel": {
        "id": "prcl_...",
        "object": "Parcel",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "length": 10.0,
        "width": 8.0,
        "height": 4.0,
        "predefined_package": null,
        "weight": 32.0
      },
      "customs_info": null,
      "rates": [
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "GroundAdvantage",
          "delivery_date": "2026-10-26",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 6,
          "rate": "9.84",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DUXX0XXXXC08020",
            "quoted_service": "GroundAdvantage",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "12.47",
            "discount": "2.63",
            "discount_date": "2026-09-29",
            "total_freight": "9.84",
            "total_surcharges": "0.00",
            "services": {
              "DUXX0XXXXC08020": 12.47
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Priority",
          "delivery_date": "2026-10-23",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 3,
          "rate": "11.20",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DPXX0XXXXC08020",
            "quoted_service": "Priority",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "14.95",
            "discount": "3.75",
            "discount_date": "2026-09-29",
            "total_freight": "11.20",
            "total_surcharges": "0.00",
            "services": {
              "DPXX0XXXXC08020": 14.95
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Express",
          "delivery_date": "2026-10-22",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 2,
          "rate": "48.75",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DEXX0XXXXC08020",
            "quoted_service": "Express",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "52.30",
            "discount": "3.55",
            "discount_date": "2026-09-29",
            "total_freight": "48.75",
            "total_surcharges": "0.00",
            "services": {
              "DEXX0XXXXC08020": 52.3
            },
            "rdc": "04"
          },
          "usps_cubic": false
        }
      ],
      "selected_rate": {
        "id": "rate_...",
        "object": "Rate",
        "carrier_account_id": "ca_...",
        "shipment_id": "shp_...",
        "created_at": "2026-10-20T15:04:12Z",
        "service": "Priority",
        "delivery_date": "2026-10-23",
        "delivery_datetime": null,
        "delivery_date_guaranteed": false,
        "delivery_days": 3,
        "rate": "11.20",
        "carrier": "USPS",
        "rate_detail": {
          "zone": "08",
          "sku": "DPXX0XXXXC08020",
          "quoted_service": "Priority",
          "billing_weight": "32.0 OZ",
          "non_cubic_weight": "32.0 OZ",
          "volume": 320.0,
          "usps_cubic": false,
          "commercial_freight": "14.95",
          "discount": "3.75",
          "discount_date": "2026-09-29",
          "total_freight": "11.20",
          "total_surcharges": "0.00",
          "services": {
            "DPXX0XXXXC08020": 14.95
          },
          "rdc": "04"
        },
        "usps_cubic": false
      },
      "tracker": {
        "id": "trk_...",
        "object": "Tracker",
        "shipment_id": "shp_...",
        "tracking_details": [],
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "status": "unknown",
        "carrier": "USPS",
        "tracking_code": "9405500106024190341287",
        "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
      },
      "postage_label": {
        "object": "PostageLabel",
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "id": "pl_...",
        "integrated_form": null,
        "label_date": "2026-10-20",
        "label_epl2_url": null,
        "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_resolution": null,
        "label_size": null,
        "label_type": null,
        "label_file_type": "application/pdf",
        "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_zpl_url": null
      },
      "refund_status": null,
      "tracking_code": "9405500106024190341287",
      "status": null,
      "insurance": null,
      "is_return": null,
      "options": {
        "delivery_confirmation": "SIGNATURE",
        "label_format": "PDF",
        "label_size": "4X6"
      }
    },
    {
      "id": "shp_...",
      "object": "Shipment",
      "created_at": "2026-10-20T15:04:12Z",
      "updated_at": "2026-10-20T15:06:40Z",
      "reference": "order-1042-2",
      "usps_zone": "08",
      "custom_id": "order-1042-2",
      "from_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "to_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "John Doe",
        "company": null,
        "street1": "148 W 51st St",
        "street2": "Apt 4B",
        "city": "New York",
        "state": "NY",
        "zip": "10019",
        "country": "US",
        "phone": "2125550199",
        "email": "john.doe@example.com",
        "residential": true,
        "verifications": null
      },
      "return_address": null,
      "buyer_address": null,
      "parcel": {
        "id": "prcl_...",
        "object": "Parcel",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "length": 12.0,
        "width": 10.0,
        "height": 6.0,
        "predefined_package": null,
        "weight": 48.0
      },
      "customs_info": null,
      "rates": [
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "GroundAdvantage",
          "delivery_date": "2026-10-26",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 6,
          "rate": "11.62",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DUXX0XXXXC08030",
            "quoted_service": "GroundAdvantage",
            "billing_weight": "48.0 OZ",
            "non_cubic_weight": "48.0 OZ",
            "volume": 720.0,
            "usps_cubic": false,
            "commercial_freight": "14.71",
            "discount": "3.09",
            "discount_date": "2026-09-29",
            "total_freight": "11.62",
            "total_surcharges": "0.00",
            "services": {
              "DUXX0XXXXC08030": 14.71
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Priority",
          "delivery_date": "2026-10-23",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 3,
          "rate": "13.85",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DPXX0XXXXC08030",
            "quoted_service": "Priority",
            "billing_weight": "48.0 OZ",
            "non_cubic_weight": "48.0 OZ",
            "volume": 720.0,
            "usps_cubic": false,
            "commercial_freight": "18.40",
            "discount": "4.55",
            "discount_date": "2026-09-29",
            "total_freight": "13.85",
            "total_surcharges": "0.00",
            "services": {
              "DPXX0XXXXC08030": 18.4
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Express",
          "delivery_date": "2026-10-22",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 2,
          "rate": "56.10",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DEXX0XXXXC08030",
            "quoted_service": "Express",
            "billing_weight": "48.0 OZ",
            "non_cubic_weight": "48.0 OZ",
            "volume": 720.0,
            "usps_cubic": false,
            "commercial_freight": "60.15",
            "discount": "4.05",
            "discount_date": "2026-09-29",
            "total_freight": "56.10",
            "total_surcharges": "0.00",
            "services": {
              "DEXX0XXXXC08030": 60.15
            },
            "rdc": "04"
          },
          "usps_cubic": false
        }
      ],
      "selected_rate": {
        "id": "rate_...",
        "object": "Rate",
        "carrier_account_id": "ca_...",
        "shipment_id": "shp_...",
        "created_at": "2026-10-20T15:04:12Z",
        "service": "Priority",
        "delivery_date": "2026-10-23",
        "delivery_datetime": null,
        "delivery_date_guaranteed": false,
        "delivery_days": 3,
        "rate": "13.85",
        "carrier": "USPS",
        "rate_detail": {
          "zone": "08",
          "sku": "DPXX0XXXXC08030",
          "quoted_service": "Priority",
          "billing_weight": "48.0 OZ",
          "non_cubic_weight": "48.0 OZ",
          "volume": 720.0,
          "usps_cubic": false,
          "commercial_freight": "18.40",
          "discount": "4.55",
          "discount_date": "2026-09-29",
          "total_freight": "13.85",
          "total_surcharges": "0.00",
          "services": {
            "DPXX0XXXXC08030": 18.4
          },
          "rdc": "04"
        },
        "usps_cubic": false
      },
      "tracker": {
        "id": "trk_...",
        "object": "Tracker",
        "shipment_id": "shp_...",
        "tracking_details": [],
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "status": "unknown",
        "carrier": "USPS",
        "tracking_code": "9405500106024190341294",
        "public_url": "https://tracking.parcelshop.com/9405500106024190341294"
      },
      "postage_label": {
        "object": "PostageLabel",
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "id": "pl_...",
        "integrated_form": null,
        "label_date": "2026-10-20",
        "label_epl2_url": null,
        "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_resolution": null,
        "label_size": null,
        "label_type": null,
        "label_file_type": "application/pdf",
        "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_zpl_url": null
      },
      "refund_status": null,
      "tracking_code": "9405500106024190341294",
      "status": null,
      "insurance": null,
      "is_return": null,
      "options": {
        "delivery_confirmation": "SIGNATURE",
        "label_format": "PDF",
        "label_size": "4X6"
      }
    }
  ],
  "rates": [
    {
      "object": "Rate",
      "carrier": "USPS",
      "service": "GroundAdvantage",
      "rate": "21.46",
      "currency": "USD"
    },
    {
      "object": "Rate",
      "carrier": "USPS",
      "service": "Priority",
      "rate": "25.05",
      "currency": "USD"
    },
    {
      "object": "Rate",
      "carrier": "USPS",
      "service": "Express",
      "rate": "104.85",
      "currency": "USD"
    }
  ],
  "carrier": "USPS",
  "service": "Priority",
  "messages": []
}

An Order groups shipments that share an origin and a destination, so they can be rated and bought together. Its rates hold only the carrier and service combinations every shipment can use, with the amounts summed.

Parameter Type Specification
id string Unique identifier, begins with "order_"
object string "Order"
to_address Address The destination address shared by all shipments
from_address Address The origin address shared by all shipments
shipments Shipment[] Array of Shipment objects in the order
rates object[] One { object: "Rate", carrier, service, rate, currency } entry for each carrier and service every shipment can use, with rate summed across the shipments. Buy the order with its carrier and service.
carrier string The carrier of the order's first carrier account, USPS by default. Set when the order is created
service string The service used to purchase the order, or null if not yet purchased
messages object[] Always empty, kept for compatibility
created_at datetime When the order was created
updated_at datetime When the order was last updated

Create an Order

POST/api/v1/orders

curl -X POST https://www.vanlo.com/api/v1/orders \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "order": {
        "to_address": {
          "name": "John Doe",
          "street1": "148 W 51st St",
          "street2": "Apt 4B",
          "city": "New York",
          "state": "NY",
          "zip": "10019",
          "country": "US",
          "phone": "2125550199",
          "email": "john.doe@example.com",
          "residential": true
        },
        "from_address": {
          "name": "Jane Smith",
          "company": "Acme Goods",
          "street1": "417 Montgomery St",
          "street2": "Floor 5",
          "city": "San Francisco",
          "state": "CA",
          "zip": "94104",
          "country": "US",
          "phone": "4155550100",
          "email": "shipping@acme.example"
        },
        "carrier_accounts": [
          "ca_..."
        ],
        "shipments": [
          {
            "parcel": {
              "length": 10.0,
              "width": 8.0,
              "height": 4.0,
              "weight": 32.0
            },
            "reference": "order-1042-1",
            "custom_id": "order-1042-1",
            "options": {
              "label_format": "PDF",
              "delivery_confirmation": "SIGNATURE"
            }
          },
          {
            "parcel": {
              "length": 12.0,
              "width": 10.0,
              "height": 6.0,
              "weight": 48.0
            },
            "reference": "order-1042-2",
            "custom_id": "order-1042-2",
            "options": {
              "label_format": "PDF",
              "delivery_confirmation": "SIGNATURE"
            }
          }
        ]
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

order = Vanlo::Order.create(
  to_address: {
    name: 'John Doe',
    street1: '148 W 51st St',
    street2: 'Apt 4B',
    city: 'New York',
    state: 'NY',
    zip: '10019',
    country: 'US',
    phone: '2125550199',
    email: 'john.doe@example.com',
    residential: true
  },
  from_address: {
    name: 'Jane Smith',
    company: 'Acme Goods',
    street1: '417 Montgomery St',
    street2: 'Floor 5',
    city: 'San Francisco',
    state: 'CA',
    zip: '94104',
    country: 'US',
    phone: '4155550100',
    email: 'shipping@acme.example'
  },
  carrier_accounts: ['ca_...'],
  shipments: [
    {
      parcel: {
        length: 10.0,
        width: 8.0,
        height: 4.0,
        weight: 32.0
      },
      reference: 'order-1042-1',
      custom_id: 'order-1042-1',
      options: {
        label_format: 'PDF',
        delivery_confirmation: 'SIGNATURE'
      }
    },
    {
      parcel: {
        length: 12.0,
        width: 10.0,
        height: 6.0,
        weight: 48.0
      },
      reference: 'order-1042-2',
      custom_id: 'order-1042-2',
      options: {
        label_format: 'PDF',
        delivery_confirmation: 'SIGNATURE'
      }
    }
  ]
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

order = vanlo.Order.create(
  to_address={
    "name": "John Doe",
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": True
  },
  from_address={
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example"
  },
  carrier_accounts=["ca_..."],
  shipments=[
    {
      "parcel": {
        "length": 10.0,
        "width": 8.0,
        "height": 4.0,
        "weight": 32.0
      },
      "reference": "order-1042-1",
      "custom_id": "order-1042-1",
      "options": {
        "label_format": "PDF",
        "delivery_confirmation": "SIGNATURE"
      }
    },
    {
      "parcel": {
        "length": 12.0,
        "width": 10.0,
        "height": 6.0,
        "weight": 48.0
      },
      "reference": "order-1042-2",
      "custom_id": "order-1042-2",
      "options": {
        "label_format": "PDF",
        "delivery_confirmation": "SIGNATURE"
      }
    }
  ]
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$order = \Vanlo\Order::create(array(
  'to_address' => array(
    'name' => 'John Doe',
    'street1' => '148 W 51st St',
    'street2' => 'Apt 4B',
    'city' => 'New York',
    'state' => 'NY',
    'zip' => '10019',
    'country' => 'US',
    'phone' => '2125550199',
    'email' => 'john.doe@example.com',
    'residential' => true
  ),
  'from_address' => array(
    'name' => 'Jane Smith',
    'company' => 'Acme Goods',
    'street1' => '417 Montgomery St',
    'street2' => 'Floor 5',
    'city' => 'San Francisco',
    'state' => 'CA',
    'zip' => '94104',
    'country' => 'US',
    'phone' => '4155550100',
    'email' => 'shipping@acme.example'
  ),
  'carrier_accounts' => array('ca_...'),
  'shipments' => array(
    array(
      'parcel' => array(
        'length' => 10.0,
        'width' => 8.0,
        'height' => 4.0,
        'weight' => 32.0
      ),
      'reference' => 'order-1042-1',
      'custom_id' => 'order-1042-1',
      'options' => array(
        'label_format' => 'PDF',
        'delivery_confirmation' => 'SIGNATURE'
      )
    ),
    array(
      'parcel' => array(
        'length' => 12.0,
        'width' => 10.0,
        'height' => 6.0,
        'weight' => 48.0
      ),
      'reference' => 'order-1042-2',
      'custom_id' => 'order-1042-2',
      'options' => array(
        'label_format' => 'PDF',
        'delivery_confirmation' => 'SIGNATURE'
      )
    )
  )
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Order order = Order.Create(new Dictionary<string, object>() {
    { "to_address", new Dictionary<string, object>() {
        { "name", "John Doe" },
        { "street1", "148 W 51st St" },
        { "street2", "Apt 4B" },
        { "city", "New York" },
        { "state", "NY" },
        { "zip", "10019" },
        { "country", "US" },
        { "phone", "2125550199" },
        { "email", "john.doe@example.com" },
        { "residential", true }
    } },
    { "from_address", new Dictionary<string, object>() {
        { "name", "Jane Smith" },
        { "company", "Acme Goods" },
        { "street1", "417 Montgomery St" },
        { "street2", "Floor 5" },
        { "city", "San Francisco" },
        { "state", "CA" },
        { "zip", "94104" },
        { "country", "US" },
        { "phone", "4155550100" },
        { "email", "shipping@acme.example" }
    } },
    { "carrier_accounts", new List<string>() { "ca_..." } },
    { "shipments", new List<Dictionary<string, object>>() {
        new Dictionary<string, object>() {
            { "parcel", new Dictionary<string, object>() {
                { "length", 10.0 },
                { "width", 8.0 },
                { "height", 4.0 },
                { "weight", 32.0 }
            } },
            { "reference", "order-1042-1" },
            { "custom_id", "order-1042-1" },
            { "options", new Dictionary<string, object>() {
                { "label_format", "PDF" },
                { "delivery_confirmation", "SIGNATURE" }
            } }
        },
        new Dictionary<string, object>() {
            { "parcel", new Dictionary<string, object>() {
                { "length", 12.0 },
                { "width", 10.0 },
                { "height", 6.0 },
                { "weight", 48.0 }
            } },
            { "reference", "order-1042-2" },
            { "custom_id", "order-1042-2" },
            { "options", new Dictionary<string, object>() {
                { "label_format", "PDF" },
                { "delivery_confirmation", "SIGNATURE" }
            } }
        }
    } }
});

Creates an order and rates each of its shipments. Send service to buy every shipment in the same request.

Parameters

Parameter Type Specification
to_addressrequired Address Destination address shared by all shipments in the order
from_addressrequired Address Origin address shared by all shipments in the order
shipmentsrequired object[] 1 to 100 shipments, each with the fields below
carrier_accounts string[] Carrier account ids to get rates from. Default: USPS
service string If provided, triggers create-and-buy: all shipments are purchased immediately with this service

Each entry of shipments:

Parameter Type Specification
parcelrequired Parcel Package dimensions and weight
customs_info CustomsInfo Customs information for international shipments
carrier_accounts string[] Override the order-level carrier_accounts for this shipment
options Options Shipment options. On an international Order that may ship with FedEx or UPS send options.duty_payment on every shipment to say who pays duties and taxes.
reference string Arbitrary reference string for this shipment
custom_id string Your key for this shipment, as on Create a Shipment. Unlike there, a custom_id whose shipment already belongs to an Order is a conflict even while it can still be bought, so replaying an Order request does not update it.
return_address Address Return address if different from the order's from_address
buyer_address Address Buyer address if different from the order's to_address

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Each shipment custom_id must be unique within an order. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "shipments[0]",
        "message": "custom_id must be unique within an order"
      },
      {
        "field": "shipments[1]",
        "message": "custom_id must be unique within an order"
      }
    ]
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Address not found by id for to_address field. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for INVALID_OPTIONS:

{
  "error": {
    "code": "INVALID_OPTIONS",
    "message": "Invalid options. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "duty_payment",
        "message": "type must be one of: SENDER, THIRD_PARTY, RECEIVER, BUYER"
      }
    ]
  }
}

Response for CONFLICT:

{
  "id": "shp_...",
  "object": "Shipment",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "reference": "order-1042-1",
  "usps_zone": "08",
  "custom_id": "order-1042-1",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "return_address": null,
  "buyer_address": null,
  "parcel": {
    "id": "prcl_...",
    "object": "Parcel",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "length": 10.0,
    "width": 8.0,
    "height": 4.0,
    "predefined_package": null,
    "weight": 32.0
  },
  "customs_info": null,
  "rates": [
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "GroundAdvantage",
      "delivery_date": "2026-10-26",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 6,
      "rate": "9.84",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DUXX0XXXXC08020",
        "quoted_service": "GroundAdvantage",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "12.47",
        "discount": "2.63",
        "discount_date": "2026-09-29",
        "total_freight": "9.84",
        "total_surcharges": "0.00",
        "services": {
          "DUXX0XXXXC08020": 12.47
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Priority",
      "delivery_date": "2026-10-23",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 3,
      "rate": "11.20",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DPXX0XXXXC08020",
        "quoted_service": "Priority",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "14.95",
        "discount": "3.75",
        "discount_date": "2026-09-29",
        "total_freight": "11.20",
        "total_surcharges": "0.00",
        "services": {
          "DPXX0XXXXC08020": 14.95
        },
        "rdc": "04"
      },
      "usps_cubic": false
    },
    {
      "id": "rate_...",
      "object": "Rate",
      "carrier_account_id": "ca_...",
      "shipment_id": "shp_...",
      "created_at": "2026-10-20T15:04:12Z",
      "service": "Express",
      "delivery_date": "2026-10-22",
      "delivery_datetime": null,
      "delivery_date_guaranteed": false,
      "delivery_days": 2,
      "rate": "48.75",
      "carrier": "USPS",
      "rate_detail": {
        "zone": "08",
        "sku": "DEXX0XXXXC08020",
        "quoted_service": "Express",
        "billing_weight": "32.0 OZ",
        "non_cubic_weight": "32.0 OZ",
        "volume": 320.0,
        "usps_cubic": false,
        "commercial_freight": "52.30",
        "discount": "3.55",
        "discount_date": "2026-09-29",
        "total_freight": "48.75",
        "total_surcharges": "0.00",
        "services": {
          "DEXX0XXXXC08020": 52.3
        },
        "rdc": "04"
      },
      "usps_cubic": false
    }
  ],
  "selected_rate": {
    "id": "rate_...",
    "object": "Rate",
    "carrier_account_id": "ca_...",
    "shipment_id": "shp_...",
    "created_at": "2026-10-20T15:04:12Z",
    "service": "Priority",
    "delivery_date": "2026-10-23",
    "delivery_datetime": null,
    "delivery_date_guaranteed": false,
    "delivery_days": 3,
    "rate": "11.20",
    "carrier": "USPS",
    "rate_detail": {
      "zone": "08",
      "sku": "DPXX0XXXXC08020",
      "quoted_service": "Priority",
      "billing_weight": "32.0 OZ",
      "non_cubic_weight": "32.0 OZ",
      "volume": 320.0,
      "usps_cubic": false,
      "commercial_freight": "14.95",
      "discount": "3.75",
      "discount_date": "2026-09-29",
      "total_freight": "11.20",
      "total_surcharges": "0.00",
      "services": {
        "DPXX0XXXXC08020": 14.95
      },
      "rdc": "04"
    },
    "usps_cubic": false
  },
  "tracker": {
    "id": "trk_...",
    "object": "Tracker",
    "shipment_id": "shp_...",
    "tracking_details": [],
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "status": "unknown",
    "carrier": "USPS",
    "tracking_code": "9405500106024190341287",
    "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
  },
  "postage_label": {
    "object": "PostageLabel",
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "id": "pl_...",
    "integrated_form": null,
    "label_date": "2026-10-20",
    "label_epl2_url": null,
    "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_resolution": null,
    "label_size": null,
    "label_type": null,
    "label_file_type": "application/pdf",
    "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
    "label_zpl_url": null
  },
  "refund_status": null,
  "tracking_code": "9405500106024190341287",
  "status": null,
  "insurance": null,
  "is_return": null,
  "options": {
    "delivery_confirmation": "SIGNATURE",
    "label_format": "PDF",
    "label_size": "4X6"
  },
  "error": {
    "code": "CONFLICT",
    "message": "A shipment with this custom_id already exists and cannot be updated. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "shipments[0]",
        "message": "custom_id already belongs to an active shipment"
      }
    ]
  }
}

Response for PAYMENT_REQUIRED:

{
  "error": {
    "code": "PAYMENT_REQUIRED",
    "message": "Insufficient funds. Please check your billing settings at http://www.vanlo.com/balance. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Balance",
        "message": "Your balance is too low to purchase this label. Please add funds on the Balance page before buying."
      }
    ]
  }
}

Response for CARRIER_REJECTED_ADDRESS:

{
  "error": {
    "code": "CARRIER_REJECTED_ADDRESS",
    "message": "The carrier rejected the destination address. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Backend",
        "message": "USPS rejected this shipment: bad zip code"
      }
    ]
  }
}

Response for EXTERNAL_SERVICE_ERROR:

{
  "error": {
    "code": "EXTERNAL_SERVICE_ERROR",
    "message": "Unexpected response from our service provider has been received while processing your request. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "shp_...:Backend",
        "message": "OnTrac could not create this label. Please contact support if it does not clear."
      }
    ]
  }
}

Response for TOO_MANY_REQUESTS:

{
  "error": {
    "code": "TOO_MANY_REQUESTS",
    "message": "Too many label purchases in flight for this account. Please retry shortly. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [],
    "details": {
      "retry_after": 2
    }
  }
}

Returns the Order with its combined rates, and with every label bought when service is sent.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 A required field is missing or has the wrong shape, or two shipments share a custom_id. error.errors names each field.
NOT_FOUND 404 An address, parcel or customs info sent by id is not one of yours.
INVALID_OPTIONS 422 A shipment's options value is not allowed, such as a malformed duty_payment.
CONFLICT 409 A custom_id belongs to a shipment already in an Order, or one that can no longer be updated. That shipment is returned beside error.
PAYMENT_REQUIRED 402 With service, your balance does not cover the labels.
CARRIER_REJECTED_ADDRESS 422 Every carrier refused the destination address. error.errors carries the reason.
EXTERNAL_SERVICE_ERROR 424 A carrier rejected or failed one of the shipments. error.errors names the shipment and its reason; the most severe failure decides the status.
TOO_MANY_REQUESTS 429 Too many label purchases are running for your account at once. The Retry-After header gives the wait in seconds.

Buy an Order

POST/api/v1/orders/:id/buy

curl -X POST https://www.vanlo.com/api/v1/orders/order_.../buy \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "carrier": "USPS",
      "service": "Priority"
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

order = Vanlo::Order.retrieve('order_...')
order.buy(carrier: 'USPS', service: 'Priority')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

order = vanlo.Order.retrieve('order_...')
order.buy(carrier='USPS', service='Priority')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$order = \Vanlo\Order::retrieve('order_...');
$order->buy(array(
  'carrier' => 'USPS',
  'service' => 'Priority'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Order order = Order.Retrieve("order_...");
order.Buy("USPS", "Priority");

Buys every shipment in the order with one carrier and service from the order's rates. An order is bought whole or not at all: when one shipment fails, the labels already bought for the order are refunded.

Parameters

Parameter Type Specification
carrierrequired string The carrier to purchase with (e.g. "USPS")
servicerequired string The service to purchase with (e.g. "Priority")

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "One or more shipments already have postage. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for PAYMENT_REQUIRED:

{
  "error": {
    "code": "PAYMENT_REQUIRED",
    "message": "Insufficient funds. Please check your billing settings at http://www.vanlo.com/balance. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "Balance",
        "message": "Your balance is too low to purchase this label. Please add funds on the Balance page before buying."
      }
    ]
  }
}

Response for EXTERNAL_SERVICE_ERROR:

{
  "error": {
    "code": "EXTERNAL_SERVICE_ERROR",
    "message": "Unexpected response from our service provider has been received while processing your request. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "shp_...:Backend",
        "message": "OnTrac could not create this label. Please contact support if it does not clear."
      }
    ]
  }
}

Response for LOCKED:

{
  "error": {
    "code": "LOCKED",
    "message": "Another resource is creating at the moment. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for TOO_MANY_REQUESTS:

{
  "error": {
    "code": "TOO_MANY_REQUESTS",
    "message": "Too many label purchases in flight for this account. Please retry shortly. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [],
    "details": {
      "retry_after": 2
    }
  }
}

Returns the Order with carrier and service set, and a label on every shipment.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 carrier or service is missing or matches no rate, a shipment already has a label, or the order is past its 72-hour purchase window.
NOT_FOUND 404 No order of yours has this id.
PAYMENT_REQUIRED 402 Your balance does not cover the labels.
EXTERNAL_SERVICE_ERROR 424 A carrier rejected or failed one of the shipments. error.errors names the shipment and its reason; the most severe failure decides the status.
LOCKED 429 This order is already being bought.
TOO_MANY_REQUESTS 429 Too many label purchases are running for your account at once. The Retry-After header gives the wait in seconds.

Retrying a purchase after a timeout is covered in the Retries and Timeouts Guide.

Retrieve an Order

GET/api/v1/orders/:id

curl https://www.vanlo.com/api/v1/orders/order_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Order.retrieve('order_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Order.retrieve('order_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$order = \Vanlo\Order::retrieve('order_...');
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Order order = Order.Retrieve("order_...");

Retrieves an order by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the order

Returns

Response:

{
  "id": "order_...",
  "object": "Order",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "shipments": [
    {
      "id": "shp_...",
      "object": "Shipment",
      "created_at": "2026-10-20T15:04:12Z",
      "updated_at": "2026-10-20T15:06:40Z",
      "reference": "order-1042-1",
      "usps_zone": "08",
      "custom_id": "order-1042-1",
      "from_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "to_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "John Doe",
        "company": null,
        "street1": "148 W 51st St",
        "street2": "Apt 4B",
        "city": "New York",
        "state": "NY",
        "zip": "10019",
        "country": "US",
        "phone": "2125550199",
        "email": "john.doe@example.com",
        "residential": true,
        "verifications": null
      },
      "return_address": null,
      "buyer_address": null,
      "parcel": {
        "id": "prcl_...",
        "object": "Parcel",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "length": 10.0,
        "width": 8.0,
        "height": 4.0,
        "predefined_package": null,
        "weight": 32.0
      },
      "customs_info": null,
      "rates": [
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "GroundAdvantage",
          "delivery_date": "2026-10-26",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 6,
          "rate": "9.84",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DUXX0XXXXC08020",
            "quoted_service": "GroundAdvantage",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "12.47",
            "discount": "2.63",
            "discount_date": "2026-09-29",
            "total_freight": "9.84",
            "total_surcharges": "0.00",
            "services": {
              "DUXX0XXXXC08020": 12.47
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Priority",
          "delivery_date": "2026-10-23",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 3,
          "rate": "11.20",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DPXX0XXXXC08020",
            "quoted_service": "Priority",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "14.95",
            "discount": "3.75",
            "discount_date": "2026-09-29",
            "total_freight": "11.20",
            "total_surcharges": "0.00",
            "services": {
              "DPXX0XXXXC08020": 14.95
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Express",
          "delivery_date": "2026-10-22",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 2,
          "rate": "48.75",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DEXX0XXXXC08020",
            "quoted_service": "Express",
            "billing_weight": "32.0 OZ",
            "non_cubic_weight": "32.0 OZ",
            "volume": 320.0,
            "usps_cubic": false,
            "commercial_freight": "52.30",
            "discount": "3.55",
            "discount_date": "2026-09-29",
            "total_freight": "48.75",
            "total_surcharges": "0.00",
            "services": {
              "DEXX0XXXXC08020": 52.3
            },
            "rdc": "04"
          },
          "usps_cubic": false
        }
      ],
      "selected_rate": {
        "id": "rate_...",
        "object": "Rate",
        "carrier_account_id": "ca_...",
        "shipment_id": "shp_...",
        "created_at": "2026-10-20T15:04:12Z",
        "service": "Priority",
        "delivery_date": "2026-10-23",
        "delivery_datetime": null,
        "delivery_date_guaranteed": false,
        "delivery_days": 3,
        "rate": "11.20",
        "carrier": "USPS",
        "rate_detail": {
          "zone": "08",
          "sku": "DPXX0XXXXC08020",
          "quoted_service": "Priority",
          "billing_weight": "32.0 OZ",
          "non_cubic_weight": "32.0 OZ",
          "volume": 320.0,
          "usps_cubic": false,
          "commercial_freight": "14.95",
          "discount": "3.75",
          "discount_date": "2026-09-29",
          "total_freight": "11.20",
          "total_surcharges": "0.00",
          "services": {
            "DPXX0XXXXC08020": 14.95
          },
          "rdc": "04"
        },
        "usps_cubic": false
      },
      "tracker": {
        "id": "trk_...",
        "object": "Tracker",
        "shipment_id": "shp_...",
        "tracking_details": [],
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "status": "unknown",
        "carrier": "USPS",
        "tracking_code": "9405500106024190341287",
        "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
      },
      "postage_label": {
        "object": "PostageLabel",
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "id": "pl_...",
        "integrated_form": null,
        "label_date": "2026-10-20",
        "label_epl2_url": null,
        "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_resolution": null,
        "label_size": null,
        "label_type": null,
        "label_file_type": "application/pdf",
        "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_zpl_url": null
      },
      "refund_status": null,
      "tracking_code": "9405500106024190341287",
      "status": null,
      "insurance": null,
      "is_return": null,
      "options": {
        "delivery_confirmation": "SIGNATURE",
        "label_format": "PDF",
        "label_size": "4X6"
      }
    },
    {
      "id": "shp_...",
      "object": "Shipment",
      "created_at": "2026-10-20T15:04:12Z",
      "updated_at": "2026-10-20T15:06:40Z",
      "reference": "order-1042-2",
      "usps_zone": "08",
      "custom_id": "order-1042-2",
      "from_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "Jane Smith",
        "company": "Acme Goods",
        "street1": "417 Montgomery St",
        "street2": "Floor 5",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94104",
        "country": "US",
        "phone": "4155550100",
        "email": "shipping@acme.example",
        "residential": null,
        "verifications": null
      },
      "to_address": {
        "id": "adr_...",
        "object": "Address",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "name": "John Doe",
        "company": null,
        "street1": "148 W 51st St",
        "street2": "Apt 4B",
        "city": "New York",
        "state": "NY",
        "zip": "10019",
        "country": "US",
        "phone": "2125550199",
        "email": "john.doe@example.com",
        "residential": true,
        "verifications": null
      },
      "return_address": null,
      "buyer_address": null,
      "parcel": {
        "id": "prcl_...",
        "object": "Parcel",
        "created_at": "2026-10-20T15:04:11Z",
        "updated_at": "2026-10-20T15:04:11Z",
        "length": 12.0,
        "width": 10.0,
        "height": 6.0,
        "predefined_package": null,
        "weight": 48.0
      },
      "customs_info": null,
      "rates": [
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "GroundAdvantage",
          "delivery_date": "2026-10-26",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 6,
          "rate": "11.62",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DUXX0XXXXC08030",
            "quoted_service": "GroundAdvantage",
            "billing_weight": "48.0 OZ",
            "non_cubic_weight": "48.0 OZ",
            "volume": 720.0,
            "usps_cubic": false,
            "commercial_freight": "14.71",
            "discount": "3.09",
            "discount_date": "2026-09-29",
            "total_freight": "11.62",
            "total_surcharges": "0.00",
            "services": {
              "DUXX0XXXXC08030": 14.71
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Priority",
          "delivery_date": "2026-10-23",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 3,
          "rate": "13.85",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DPXX0XXXXC08030",
            "quoted_service": "Priority",
            "billing_weight": "48.0 OZ",
            "non_cubic_weight": "48.0 OZ",
            "volume": 720.0,
            "usps_cubic": false,
            "commercial_freight": "18.40",
            "discount": "4.55",
            "discount_date": "2026-09-29",
            "total_freight": "13.85",
            "total_surcharges": "0.00",
            "services": {
              "DPXX0XXXXC08030": 18.4
            },
            "rdc": "04"
          },
          "usps_cubic": false
        },
        {
          "id": "rate_...",
          "object": "Rate",
          "carrier_account_id": "ca_...",
          "shipment_id": "shp_...",
          "created_at": "2026-10-20T15:04:12Z",
          "service": "Express",
          "delivery_date": "2026-10-22",
          "delivery_datetime": null,
          "delivery_date_guaranteed": false,
          "delivery_days": 2,
          "rate": "56.10",
          "carrier": "USPS",
          "rate_detail": {
            "zone": "08",
            "sku": "DEXX0XXXXC08030",
            "quoted_service": "Express",
            "billing_weight": "48.0 OZ",
            "non_cubic_weight": "48.0 OZ",
            "volume": 720.0,
            "usps_cubic": false,
            "commercial_freight": "60.15",
            "discount": "4.05",
            "discount_date": "2026-09-29",
            "total_freight": "56.10",
            "total_surcharges": "0.00",
            "services": {
              "DEXX0XXXXC08030": 60.15
            },
            "rdc": "04"
          },
          "usps_cubic": false
        }
      ],
      "selected_rate": {
        "id": "rate_...",
        "object": "Rate",
        "carrier_account_id": "ca_...",
        "shipment_id": "shp_...",
        "created_at": "2026-10-20T15:04:12Z",
        "service": "Priority",
        "delivery_date": "2026-10-23",
        "delivery_datetime": null,
        "delivery_date_guaranteed": false,
        "delivery_days": 3,
        "rate": "13.85",
        "carrier": "USPS",
        "rate_detail": {
          "zone": "08",
          "sku": "DPXX0XXXXC08030",
          "quoted_service": "Priority",
          "billing_weight": "48.0 OZ",
          "non_cubic_weight": "48.0 OZ",
          "volume": 720.0,
          "usps_cubic": false,
          "commercial_freight": "18.40",
          "discount": "4.55",
          "discount_date": "2026-09-29",
          "total_freight": "13.85",
          "total_surcharges": "0.00",
          "services": {
            "DPXX0XXXXC08030": 18.4
          },
          "rdc": "04"
        },
        "usps_cubic": false
      },
      "tracker": {
        "id": "trk_...",
        "object": "Tracker",
        "shipment_id": "shp_...",
        "tracking_details": [],
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "status": "unknown",
        "carrier": "USPS",
        "tracking_code": "9405500106024190341294",
        "public_url": "https://tracking.parcelshop.com/9405500106024190341294"
      },
      "postage_label": {
        "object": "PostageLabel",
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-20T15:06:40Z",
        "id": "pl_...",
        "integrated_form": null,
        "label_date": "2026-10-20",
        "label_epl2_url": null,
        "label_pdf_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_resolution": null,
        "label_size": null,
        "label_type": null,
        "label_file_type": "application/pdf",
        "label_url": "https://www.vanlo.com/rails/active_storage/blobs/redirect/.../label.pdf",
        "label_zpl_url": null
      },
      "refund_status": null,
      "tracking_code": "9405500106024190341294",
      "status": null,
      "insurance": null,
      "is_return": null,
      "options": {
        "delivery_confirmation": "SIGNATURE",
        "label_format": "PDF",
        "label_size": "4X6"
      }
    }
  ],
  "rates": [
    {
      "object": "Rate",
      "carrier": "USPS",
      "service": "GroundAdvantage",
      "rate": "21.46",
      "currency": "USD"
    },
    {
      "object": "Rate",
      "carrier": "USPS",
      "service": "Priority",
      "rate": "25.05",
      "currency": "USD"
    },
    {
      "object": "Rate",
      "carrier": "USPS",
      "service": "Express",
      "rate": "104.85",
      "currency": "USD"
    }
  ],
  "carrier": "USPS",
  "service": "Priority",
  "messages": []
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Order.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No order of yours has this id.

Reports

Report Object

A finished shipment Report:

{
  "id": "shprep_...",
  "object": "ShipmentReport",
  "created_at": "2026-10-20T15:30:02Z",
  "updated_at": "2026-10-20T15:31:47Z",
  "start_date": "2026-09-20",
  "end_date": "2026-10-19",
  "status": "ready",
  "url": "https://s3.us-west-2.amazonaws.com/vanlo.com/...?response-content-disposition=attachment%3B%20filename%3D%22shipments-2026-09-20-2026-10-19.csv.zip%22&response-content-type=application%2Fzip&X-Amz-Expires=3600&X-Amz-Signature=...",
  "url_expires_at": "2026-10-20T16:42:10.884Z"
}

A CSV export of one kind of record over a date range, generated in the background. url stays null until status is ready.

Type Object Name ID Prefix
shipment ShipmentReport shprep_
payment_log PaymentLogReport plrep_
shipment_invoice ShipmentInvoiceReport shpinvrep_
refund RefundReport refrep_
tracking TrackingReport trkrep_
invoice_item InvoiceItemReport report_
balance_snapshot BalanceSnapshotReport report_
fedex_detail FedExDetailReport fdxrep_
Parameter Type Specification
id string Unique identifier, begins with a type-specific prefix (e.g., "shprep_" for shipment reports)
object string The type-specific object name (e.g., "ShipmentReport")
created_at datetime When the report was created
updated_at datetime When the report was last updated
start_date date The start date of the report's date range
end_date date The end date of the report's date range
status string Current status: "new", "generating", "ready", or "error"
url string URL to download the report CSV (zipped). Expires after 1 hour. Null while generating
url_expires_at datetime When the download URL will expire. Null while generating

Create a Report

POST/api/v1/reports/:type

curl -X POST https://www.vanlo.com/api/v1/reports/shipment \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "start_date": "2026-09-20",
      "end_date": "2026-10-19",
      "send_email": true,
      "send_email_address": "reports@acme.example"
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

report = Vanlo::Report.create(
  type: 'shipment',
  start_date: '2026-09-20',
  end_date: '2026-10-19',
  send_email: true,
  send_email_address: 'reports@acme.example'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

report = vanlo.Report.create(
  type="shipment",
  start_date="2026-09-20",
  end_date="2026-10-19",
  send_email=True,
  send_email_address="reports@acme.example"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$report = \Vanlo\Report::create(array(
  'type' => 'shipment',
  'start_date' => '2026-09-20',
  'end_date' => '2026-10-19',
  'send_email' => true,
  'send_email_address' => 'reports@acme.example'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Report report = Report.Create(new Dictionary<string, object>() {
    { "type", "shipment" },
    { "start_date", "2026-09-20" },
    { "end_date", "2026-10-19" },
    { "send_email", true },
    { "send_email_address", "reports@acme.example" }
});

Starts a report of one type over a date range of up to 31 days. Poll it until it is ready, or send send_email to be emailed when it is.

Parameters

Parameter Type Specification
type string The type of report to generate. One of: shipment, payment_log, shipment_invoice, refund, tracking, invoice_item, balance_snapshot, fedex_detail
start_date date Start date for the report (inclusive). Defaults to 31 days before end_date, or before today when neither is sent
end_date date End date for the report (inclusive). Defaults to start_date + 31 days if omitted
send_email boolean If true, send an email when the report is ready. Defaults to false
send_email_address string Email address to send the report to. Defaults to the account email if omitted

Returns

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid parameters were passed and the record could not be persisted. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "end_date",
        "message": "The date range covers more than 31 days and Invalid end date given for the report"
      }
    ]
  }
}

Returns the Report in status new, with a null url. A report that fails while generating is not an error: its status becomes error.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 type is not one of the report types.
BAD_REQUEST 400 The date range is invalid or covers more than 31 days. error.errors names the date.

List Reports

GET/api/v1/reports/:type

curl -G https://www.vanlo.com/api/v1/reports/shipment \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -d 'page_size=2' \
  -d 'start_datetime=2026-09-01T00:00:00Z'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Report.all(
  type: 'shipment',
  page_size: 2,
  start_datetime: '2026-09-01T00:00:00Z'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Report.all(
  type="shipment",
  page_size=2,
  start_datetime="2026-09-01T00:00:00Z"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$reports = \Vanlo\Report::all(array(
  'type' => 'shipment',
  'page_size' => 2,
  'start_datetime' => '2026-09-01T00:00:00Z'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

ReportList reportList = Report.List(new Dictionary<string, object>() {
    { "type", "shipment" },
    { "page_size", 2 },
    { "start_datetime", "2026-09-01T00:00:00Z" }
});

Lists your reports of one type a page at a time. Pass before_id or after_id to say where the next page begins.

Parameters

Parameter Type Specification
type string The type of report to list. One of: shipment, payment_log, shipment_invoice, refund, tracking, invoice_item, balance_snapshot, fedex_detail
before_id string Return reports created before this id
after_id string Return reports created after this id
start_datetime datetime Only return reports created after this timestamp
end_datetime datetime Only return reports created before this timestamp
page_size integer Number of reports to return per page (default 20, max 100)

Returns

Response:

{
  "reports": [
    {
      "id": "shprep_...",
      "object": "ShipmentReport",
      "created_at": "2026-10-20T15:30:02Z",
      "updated_at": "2026-10-20T15:31:47Z",
      "start_date": "2026-09-20",
      "end_date": "2026-10-19",
      "status": "ready",
      "url": "https://s3.us-west-2.amazonaws.com/vanlo.com/...?response-content-disposition=attachment%3B%20filename%3D%22shipments-2026-09-20-2026-10-19.csv.zip%22&response-content-type=application%2Fzip&X-Amz-Expires=3600&X-Amz-Signature=...",
      "url_expires_at": "2026-10-20T16:42:10.884Z"
    },
    {
      "id": "shprep_...",
      "object": "ShipmentReport",
      "created_at": "2026-09-20T09:00:11Z",
      "updated_at": "2026-09-20T09:01:58Z",
      "start_date": "2026-08-20",
      "end_date": "2026-09-19",
      "status": "ready",
      "url": "https://s3.us-west-2.amazonaws.com/vanlo.com/...?response-content-disposition=attachment%3B%20filename%3D%22shipments-2026-08-20-2026-09-19.csv.zip%22&response-content-type=application%2Fzip&X-Amz-Expires=3600&X-Amz-Signature=...",
      "url_expires_at": "2026-10-20T16:42:10.884Z"
    }
  ],
  "has_more": true
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns an object with reports, an array of Report, and has_more, which says whether another page exists.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 type is not one of the report types.

Retrieve a Report

GET/api/v1/reports/:id

curl https://www.vanlo.com/api/v1/reports/shprep_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Report.retrieve('shprep_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Report.retrieve('shprep_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$report = \Vanlo\Report::retrieve('shprep_...');
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Report report = Report.Retrieve("shprep_...");

Retrieves a report by its id. GET /api/v1/reports/:type/:id works too.

Parameters

Parameter Type Specification
id string Unique identifier of the report

Returns

Response:

{
  "id": "shprep_...",
  "object": "ShipmentReport",
  "created_at": "2026-10-20T15:30:02Z",
  "updated_at": "2026-10-20T15:31:47Z",
  "start_date": "2026-09-20",
  "end_date": "2026-10-19",
  "status": "ready",
  "url": "https://s3.us-west-2.amazonaws.com/vanlo.com/...?response-content-disposition=attachment%3B%20filename%3D%22shipments-2026-09-20-2026-10-19.csv.zip%22&response-content-type=application%2Fzip&X-Amz-Expires=3600&X-Amz-Signature=...",
  "url_expires_at": "2026-10-20T16:42:10.884Z"
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Report.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No report of yours has this id.

Carrier Accounts

Carrier Account Object

A Carrier Account you added:

{
   "id":"ca_...",
   "object":"CarrierAccount",
   "type":"PassportGlobalAccount",
   "readable":"Passport",
   "description":"My Passport",
   "credentials":{},
   "created_at":"2026-08-09T12:00:00Z",
   "updated_at":"2026-08-09T12:00:00Z"
}

The credentials of an account you hold with a carrier, so Vanlo rates and buys on your own pricing and the carrier bills you. Accounts Vanlo provides are listed too, with credentials of null, and cannot be changed with your key.

Parameter Type Specification
id string Unique identifier, begins with "ca_"
object string "CarrierAccount"
type string The account type, e.g. "FedExAccount" or "PassportGlobalAccount"
readable string The carrier's display name, e.g. "FedEx" or "Passport"
description string Your own label for the account, or null
credentials object Always an empty object for accounts you added, and null for accounts managed by Vanlo. Credentials are write-only and are never returned
created_at datetime When the account was added
updated_at datetime When the account was last changed

Supported Carrier Account Types

The type you send on create selects the carrier and the credentials fields read; other fields are ignored.

Type Carrier Credentials
FedExAccount FedEx mode (test or prod), client_id, client_secret, account_number
UPSAccount UPS client_id, client_secret, account_number, mode (test or prod)
UniUniAccount UniUni mode (test or prod), client_id, client_secret, customer_no
DoorDashAccount DoorDash developer_id, key_id, signing_secret, pickup_external_business_id (optional)
OnTracAccount OnTrac mode (test or prod), wsid, wskey, customer_branch
VehoAccount Veho api_key, mode (sandbox or prod)
PassportGlobalAccount Passport api_key, mode (stg or prod), company_name
DhlEcsAccount DHL eCommerce client_id, client_secret, distribution_center, pickup_id
AmazonShippingAccount Amazon Shipping None — authorized at the carrier, see below

FedexAccount and UpsAccount are accepted as spellings of FedExAccount and UPSAccount on create; the response always carries the type as listed here.

A Passport account you added before Vanlo integrated Passport directly keeps the PassportGlobalAccount type but was registered under the earlier credential set, so an update on it takes api_key, company_name, email, name and phone instead of the fields above. Both kinds carry the same type in the response; an api_key rotation works on either.

Create a Carrier Account

POST/api/v1/carrier_accounts

curl -X POST https://www.vanlo.com/api/v1/carrier_accounts \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "carrier_account": {
        "type": "DhlEcsAccount",
        "description": "My DHL eCommerce",
        "credentials": {
          "client_id": "DHL_CLIENT_ID",
          "client_secret": "DHL_CLIENT_SECRET",
          "distribution_center": "USORD1",
          "pickup_id": "DHL_PICKUP_ID"
        }
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::CarrierAccount.create(
  type: 'DhlEcsAccount',
  description: 'My DHL eCommerce',
  credentials: {
    client_id: 'DHL_CLIENT_ID',
    client_secret: 'DHL_CLIENT_SECRET',
    distribution_center: 'USORD1',
    pickup_id: 'DHL_PICKUP_ID'
  }
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.CarrierAccount.create(
    type='DhlEcsAccount',
    description='My DHL eCommerce',
    credentials={
        'client_id': 'DHL_CLIENT_ID',
        'client_secret': 'DHL_CLIENT_SECRET',
        'distribution_center': 'USORD1',
        'pickup_id': 'DHL_PICKUP_ID'
    }
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$carrier_account = \Vanlo\CarrierAccount::create(array(
    'type' => 'DhlEcsAccount',
    'description' => 'My DHL eCommerce',
    'credentials' => array(
        'client_id' => 'DHL_CLIENT_ID',
        'client_secret' => 'DHL_CLIENT_SECRET',
        'distribution_center' => 'USORD1',
        'pickup_id' => 'DHL_PICKUP_ID'
    )
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

CarrierAccount carrierAccount = CarrierAccount.Create(
    new Dictionary<string, object>() {
        { "type", "DhlEcsAccount" },
        { "description", "My DHL eCommerce" },
        { "credentials", new Dictionary<string, object>() {
            { "client_id", "DHL_CLIENT_ID" },
            { "client_secret", "DHL_CLIENT_SECRET" },
            { "distribution_center", "USORD1" },
            { "pickup_id", "DHL_PICKUP_ID" }
        }}
    }
);

Adds an account with the credentials the carrier issued you. FedEx, UniUni, DoorDash, OnTrac, Veho and Passport credentials are verified with the carrier first; UPS credentials are saved as sent, and DHL eCommerce and Amazon Shipping only have their shape checked.

Parameters

Parameter Type Specification
type string Required. One of the account types
credentials object The credential fields for that type
description string Optional. Your own label for the account

Returns

Response for an Amazon Shipping account:

{
   "id":"ca_...",
   "object":"CarrierAccount",
   "type":"AmazonShippingAccount",
   "readable":"AmazonShipping",
   "description":null,
   "credentials":{},
   "created_at":"2026-08-09T12:00:00Z",
   "updated_at":"2026-08-09T12:00:00Z",
   "oauth_url":"https://ship.amazon.com/authorize?..."
}

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "type",
        "message": "is missing"
      }
    ]
  }
}

Response for PARAMETER.REQUIRED:

{
  "error": {
    "code": "PARAMETER.REQUIRED",
    "message": "Missing required parameter: carrier_account. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for VALIDATION_ERROR:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "We couldn't register these credentials with the carrier. Please double-check the credential fields and try again. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Carrier Account, ready to pass in carrier_accounts. An Amazon Shipping account also carries an oauth_url the account holder opens to authorize Vanlo, and cannot rate or buy until then.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 type is missing, blank or not supported, or credentials is not an object. error.errors names the field.
PARAMETER.REQUIRED 422 The carrier_account object is missing.
VALIDATION_ERROR 422 The carrier rejected the credentials, a credential field for the type is blank, or the carrier is in a limited pilot not enabled on your account.

List Carrier Accounts

GET/api/v1/carrier_accounts

curl https://www.vanlo.com/api/v1/carrier_accounts \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::CarrierAccount.all
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

carrier_accounts = vanlo.CarrierAccount.all()
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$carrier_accounts = \Vanlo\CarrierAccount::all();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

List<CarrierAccount> carrierAccounts = CarrierAccount.List();

Lists every carrier account available to you, the ones you added and the ones Vanlo manages, in one unpaginated array.

Parameters

This call takes no parameters.

Returns

Response:

[
   {
      "id":"ca_...",
      "object":"CarrierAccount",
      "type":"PassportGlobalAccount",
      "readable":"Passport",
      "description":"My Passport",
      "credentials":{},
      "created_at":"2026-08-09T12:00:00Z",
      "updated_at":"2026-08-09T12:00:00Z"
   },
   {
      "id":"ca_...",
      "object":"CarrierAccount",
      "type":"USPSAccount",
      "readable":"USPS",
      "description":null,
      "credentials":null,
      "created_at":"2026-01-04T09:30:00Z",
      "updated_at":"2026-01-04T09:30:00Z"
   }
]

Returns an array of Carrier Account.

On failure it returns one of the common errors; this call has none of its own.

Retrieve a Carrier Account

GET/api/v1/carrier_accounts/:id

curl https://www.vanlo.com/api/v1/carrier_accounts/ca_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::CarrierAccount.retrieve('ca_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.CarrierAccount.retrieve('ca_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$carrier_account = \Vanlo\CarrierAccount::retrieve("ca_...");
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

CarrierAccount carrierAccount = CarrierAccount.Retrieve("ca_...");

Retrieves a carrier account by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the carrier account

Returns

Response:

{
   "id":"ca_...",
   "object":"CarrierAccount",
   "type":"PassportGlobalAccount",
   "readable":"Passport",
   "description":"My Passport",
   "credentials":{},
   "created_at":"2026-08-09T12:00:00Z",
   "updated_at":"2026-08-09T12:00:00Z"
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Carrier Account.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No carrier account on your account has this id.

Update a Carrier Account

PATCH/api/v1/carrier_accounts/:id

curl -X PATCH https://www.vanlo.com/api/v1/carrier_accounts/ca_... \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "carrier_account": {
        "description": "Passport (rotated)",
        "credentials": {
          "api_key": "NEW_PASSPORT_API_KEY"
        }
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

carrier_account = Vanlo::CarrierAccount.retrieve('ca_...')
carrier_account.update(
  description: 'Passport (rotated)',
  credentials: { api_key: 'NEW_PASSPORT_API_KEY' }
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

carrier_account = vanlo.CarrierAccount.retrieve('ca_...')
carrier_account.update(
    description='Passport (rotated)',
    credentials={'api_key': 'NEW_PASSPORT_API_KEY'}
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$carrier_account = \Vanlo\CarrierAccount::retrieve("ca_...");
$carrier_account->update(array(
    'description' => 'Passport (rotated)',
    'credentials' => array('api_key' => 'NEW_PASSPORT_API_KEY')
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

CarrierAccount carrierAccount = CarrierAccount.Retrieve("ca_...");
carrierAccount.Update(
    new Dictionary<string, object>() {
        { "description", "Passport (rotated)" },
        { "credentials", new Dictionary<string, object>() {
            { "api_key", "NEW_PASSPORT_API_KEY" }
        }}
    }
);

Rotates the credentials of an account you added, renames it, or both. Send only what changes: the credential fields you send replace the stored ones one by one.

Parameters

Parameter Type Specification
id string Unique identifier of the carrier account
credentials object Replacement credential fields for the account's type
description string A new label for the account

Returns

Response for VALIDATION_ERROR:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "We couldn't register these credentials with the carrier. Please double-check the credential fields and try again. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for UNPROCESSABLE_ENTITY:

{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "This carrier account has purchased shipments, so its credentials can no longer be changed. Add a new carrier account with the new credentials instead. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for PARAMETER.INVALID_TYPE:

{
  "error": {
    "code": "PARAMETER.INVALID_TYPE",
    "message": "Expected 'credentials' to be an object. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for FORBIDDEN:

{
  "error": {
    "code": "FORBIDDEN",
    "message": "This carrier account is managed by Vanlo and cannot be modified. You can only manage carrier accounts you added yourself. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Carrier Account. Credentials of a FedEx, UPS, UniUni, DoorDash, OnTrac, Veho or native Passport account are locked once a label is bought on it; DHL eCommerce, Amazon Shipping and older Passport credentials rotate at the carrier and stay changeable.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
VALIDATION_ERROR 422 The carrier rejected the new credentials, or a credential field is blank. The stored credentials are unchanged.
UNPROCESSABLE_ENTITY 422 The credentials can no longer be changed: a label was bought on the account, or Vanlo support set it up.
PARAMETER.INVALID_TYPE 422 credentials is not an object.
FORBIDDEN 403 The account is managed by Vanlo.
NOT_FOUND 404 No carrier account on your account has this id.

Delete a Carrier Account

DELETE/api/v1/carrier_accounts/:id

curl -X DELETE https://www.vanlo.com/api/v1/carrier_accounts/ca_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

carrier_account = Vanlo::CarrierAccount.retrieve('ca_...')
carrier_account.delete
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

carrier_account = vanlo.CarrierAccount.retrieve('ca_...')
carrier_account.delete()
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$carrier_account = \Vanlo\CarrierAccount::retrieve("ca_...");
$carrier_account->delete();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

CarrierAccount carrierAccount = CarrierAccount.Retrieve("ca_...");
carrierAccount.Destroy();

Removes an account you added, so it is no longer used for rating and buying. Labels already bought on it are not affected.

Parameters

Parameter Type Specification
id string Unique identifier of the carrier account

Returns

Response for FORBIDDEN:

{
  "error": {
    "code": "FORBIDDEN",
    "message": "This carrier account is managed by Vanlo and cannot be modified. You can only manage carrier accounts you added yourself. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns an empty object.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
FORBIDDEN 403 The account is managed by Vanlo.
NOT_FOUND 404 No carrier account on your account has this id.

Trackers

Tracker Object

A Tracker:

{
  "id": "trk_...",
  "object": "Tracker",
  "shipment_id": "shp_...",
  "tracking_details": [
    {
      "object": "TrackingDetail",
      "status": "pre_transit",
      "message": "Shipping Label Created, USPS Awaiting Item",
      "datetime": "2026-10-20 15:06:42",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    },
    {
      "object": "TrackingDetail",
      "status": "in_transit",
      "message": "Accepted at USPS Origin Facility",
      "datetime": "2026-10-20 23:41:00",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    },
    {
      "object": "TrackingDetail",
      "status": "in_transit",
      "message": "Arrived at USPS Regional Origin Facility",
      "datetime": "2026-10-21 03:12:00",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    },
    {
      "object": "TrackingDetail",
      "status": "in_transit",
      "message": "In Transit to Next Facility",
      "datetime": "2026-10-21 19:05:00",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    }
  ],
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-21T19:20:13Z",
  "status": "in_transit",
  "carrier": "USPS",
  "tracking_code": "9405500106024190341287",
  "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
}

The tracking history of one package, updated as the carrier scans it. A Tracker is created with every purchased label, or on its own from a tracking code.

Parameter Type Specification
id string Unique identifier, begins with "trk_"
object string "Tracker"
shipment_id string The id of the Shipment object associated with the Tracker (if any)
tracking_details TrackingDetails[] Array of the associated TrackingDetail objects
carrier string The name of the carrier handling the shipment
status string The current status of the package, possible values are "unknown", "pre_transit", "in_transit", "out_for_delivery", "delivered", "available_for_pickup", "return_to_sender", "failure", "cancelled" or "error"
tracking_code string The tracking code provided by the carrier
public_url string URL to a publicly-accessible html page that shows tracking details for this tracker
created_at datetime When the tracker was created
updated_at datetime When the tracker was last updated

Test Tracking Codes

In test mode these codes return a fixed status and send a webhook Event to your test URL, with canned details shaped like a real carrier's. A label bought in test mode is tracked as one of them, picked at random.

tracking_code status
EZ1000000001 pre_transit
EZ2000000002 in_transit
EZ3000000003 out_for_delivery
EZ4000000004 delivered
EZ5000000005 return_to_sender
EZ6000000006 failure
EZ7000000007 unknown

Create a Tracker

POST/api/v1/trackers

curl -X POST https://www.vanlo.com/api/v1/trackers \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "tracker": {
        "tracking_code": "EZ2000000002"
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Tracker.create(
  tracking_code: 'EZ2000000002'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Tracker.create(tracking_code='EZ2000000002')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');


$tracker = \Vanlo\Tracker::create(array(
  'tracking_code' => 'EZ2000000002',
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Tracker tracker = Tracker.Create(
    new Dictionary<string, object>() { { "tracking_code", "EZ2000000002" } }
);

Starts tracking a package by its tracking code, for a label bought outside Vanlo. The carrier is detected from the code.

Parameters

Parameter Type Specification
tracking_code string The tracking code to track

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "tracking_code",
        "message": "is missing"
      }
    ]
  }
}

Response for UNPROCESSABLE_ENTITY:

{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "Unsupported carrier: CanadaPost. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Tracker.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 tracking_code is missing. error.errors names the field.
UNPROCESSABLE_ENTITY 422 The tracking code could not be tracked, such as one from a carrier Vanlo does not support. error.message carries the reason.

List Trackers

GET/api/v1/trackers

curl -G https://www.vanlo.com/api/v1/trackers \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -d 'page_size=2' \
  -d 'start_datetime=2026-10-01T00:00:00Z'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Tracker.all(
  page_size: 2,
  start_datetime: '2026-10-01T00:00:00Z'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Tracker.all(
  page_size=2,
  start_datetime="2026-10-01T00:00:00Z"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$trackers = \Vanlo\Tracker::all(array(
  'page_size' => 2,
  'start_datetime' => '2026-10-01T00:00:00Z'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

TrackerList trackerList = Tracker.List(new Dictionary<string, object>() {
    { "page_size", 2 },
    { "start_datetime", "2026-10-01T00:00:00Z" }
});

Lists your trackers a page at a time. Pass before_id or after_id to say where the next page begins.

Parameters

Parameter Type Specification
before_id string Return trackers created before this id
after_id string Return trackers created after this id
start_datetime datetime Only return trackers created after this timestamp
end_datetime datetime Only return trackers created before this timestamp
page_size integer Number of trackers to return per page (default 20, max 100)

Returns

Response:

{
  "trackers": [
    {
      "id": "trk_...",
      "object": "Tracker",
      "shipment_id": "shp_...",
      "tracking_details": [
        {
          "object": "TrackingDetail",
          "status": "pre_transit",
          "message": "Shipping Label Created, USPS Awaiting Item",
          "datetime": "2026-10-20 15:06:42",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        },
        {
          "object": "TrackingDetail",
          "status": "in_transit",
          "message": "Accepted at USPS Origin Facility",
          "datetime": "2026-10-20 23:41:00",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        },
        {
          "object": "TrackingDetail",
          "status": "in_transit",
          "message": "Arrived at USPS Regional Origin Facility",
          "datetime": "2026-10-21 03:12:00",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        },
        {
          "object": "TrackingDetail",
          "status": "in_transit",
          "message": "In Transit to Next Facility",
          "datetime": "2026-10-21 19:05:00",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        }
      ],
      "created_at": "2026-10-20T15:06:40Z",
      "updated_at": "2026-10-21T19:20:13Z",
      "status": "in_transit",
      "carrier": "USPS",
      "tracking_code": "9405500106024190341287",
      "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
    },
    {
      "id": "trk_...",
      "object": "Tracker",
      "shipment_id": "shp_...",
      "tracking_details": [
        {
          "object": "TrackingDetail",
          "status": "pre_transit",
          "message": "Shipping Label Created, USPS Awaiting Item",
          "datetime": "2026-10-17 14:22:10",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        },
        {
          "object": "TrackingDetail",
          "status": "in_transit",
          "message": "Accepted at USPS Origin Facility",
          "datetime": "2026-10-17 22:03:00",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        },
        {
          "object": "TrackingDetail",
          "status": "out_for_delivery",
          "message": "Out for Delivery",
          "datetime": "2026-10-20 12:47:00",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        },
        {
          "object": "TrackingDetail",
          "status": "delivered",
          "message": "Delivered, In/At Mailbox",
          "datetime": "2026-10-20 18:31:00",
          "source": null,
          "pod_urls": null,
          "updated_at": null,
          "created_at": null
        }
      ],
      "created_at": "2026-10-17T14:22:08Z",
      "updated_at": "2026-10-20T18:45:51Z",
      "status": "delivered",
      "carrier": "USPS",
      "tracking_code": "9405500106024190327715",
      "public_url": "https://tracking.parcelshop.com/9405500106024190327715"
    }
  ],
  "has_more": true
}

Returns an object with trackers, an array of Tracker, and has_more, which says whether another page exists.

On failure it returns one of the common errors; this call has none of its own.

Retrieve a Tracker

GET/api/v1/trackers/:id

curl https://www.vanlo.com/api/v1/trackers/trk_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Tracker.retrieve('trk_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Tracker.retrieve('trk_...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$tracker = \Vanlo\Tracker::retrieve('trk_...');
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Tracker tracker = Tracker.Retrieve("trk_...");

Retrieves a tracker by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the tracker

Returns

Response:

{
  "id": "trk_...",
  "object": "Tracker",
  "shipment_id": "shp_...",
  "tracking_details": [
    {
      "object": "TrackingDetail",
      "status": "pre_transit",
      "message": "Shipping Label Created, USPS Awaiting Item",
      "datetime": "2026-10-20 15:06:42",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    },
    {
      "object": "TrackingDetail",
      "status": "in_transit",
      "message": "Accepted at USPS Origin Facility",
      "datetime": "2026-10-20 23:41:00",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    },
    {
      "object": "TrackingDetail",
      "status": "in_transit",
      "message": "Arrived at USPS Regional Origin Facility",
      "datetime": "2026-10-21 03:12:00",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    },
    {
      "object": "TrackingDetail",
      "status": "in_transit",
      "message": "In Transit to Next Facility",
      "datetime": "2026-10-21 19:05:00",
      "source": null,
      "pod_urls": null,
      "updated_at": null,
      "created_at": null
    }
  ],
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-21T19:20:13Z",
  "status": "in_transit",
  "carrier": "USPS",
  "tracking_code": "9405500106024190341287",
  "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
}

Returns the Tracker, or null when no tracker of yours has this id.

On failure it returns one of the common errors; this call has none of its own.

Nested Objects

Objects a Tracker carries. Each one also expands in place wherever a table names it.

CarrierDetail Object

A CarrierDetail:

{
  "object": "CarrierDetail",
  "service": "Priority",
  "container_type": null,
  "origin_location": "SAN FRANCISCO CA, 94104",
  "alternate_identifier": null,
  "destination_location": "NEW YORK NY, 10019",
  "est_delivery_date_local": "2026-10-23",
  "est_delivery_time_local": null,
  "guaranteed_delivery_date": null,
  "initial_delivery_attempt": null,
  "origin_tracking_location": {
    "city": "SAN FRANCISCO",
    "state": "CA",
    "country": "US",
    "zip": "94104"
  },
  "destination_tracking_location": {
    "city": "NEW YORK",
    "state": "NY",
    "country": "US",
    "zip": "10019"
  }
}

Sent in the carrier_detail of a Tracker Event, when the carrier supplies it. These endpoints do not return it.

Parameter Type Specification
object string "CarrierDetail"
service string The service level the associated shipment was shipped with (if available)
container_type string The type of container the associated shipment was shipped in (if available)
origin_location string The location from which the package originated, stringified for presentation (if available)
alternate_identifier string The alternate identifier for this package as provided by the carrier (if available)
destination_location string The location to which the package is being sent, stringified for presentation (if available)
est_delivery_date_local string The estimated delivery date as provided by the carrier, in the local time zone (if available)
est_delivery_time_local string The estimated delivery time as provided by the carrier, in the local time zone (if available)
guaranteed_delivery_date string The date and time the carrier guarantees the package to be delivered by (if available)
initial_delivery_attempt string The date and time of the first attempt by the carrier to deliver the package (if available)
origin_tracking_location TrackingLocation The location from which the package originated
destination_tracking_location TrackingLocation The location to which the package is being sent

TrackingDetails Object

A TrackingDetail:

{
  "object": "TrackingDetail",
  "status": "in_transit",
  "message": "Accepted at USPS Origin Facility",
  "datetime": "2026-10-20 23:41:00",
  "source": null,
  "pod_urls": null,
  "updated_at": null,
  "created_at": null
}
Parameter Type Specification
object string "TrackingDetail"
status string status of the package at the time of the scan event, possible values are "unknown", "pre_transit", "in_transit", "out_for_delivery", "delivered", "available_for_pickup", "return_to_sender", "failure", "cancelled" or "error"
message string Description of the scan event
source string The carrier that reported the scan, or null
datetime string When the scan occurred, as "YYYY-MM-DD HH:MM:SS" in the time the carrier reported, without a zone
tracking_location TrackingLocation The location associated with the scan event. Sent only in Tracker Events, not by these endpoints
pod_urls string[] Proof-of-delivery image URLs, if available
created_at datetime Always null
updated_at datetime Always null

TrackingLocation Object

A TrackingLocation:

{
  "zip": "94128",
  "city": "SAN FRANCISCO",
  "state": "CA",
  "country": "US"
}
Parameter Type Specification
zip string The postal code where the scan event occurred (if available)
city string The city where the scan event occurred (if available)
state string The state where the scan event occurred (if available)
country string The country where the scan event occurred (if available)

Partner Events

The Partner Events endpoint reports USPS shipment milestones - such as a label being created, a package departing a facility, or an order being received - back to the USPS. You submit an event for one or more of your tracking codes, and Vanlo reports it to the USPS on your behalf.

Reporting is asynchronous. A successful request returns 202 Accepted: Vanlo has accepted the event for reporting, not confirmed that the USPS has already recorded it.

Create a Partner Event

POST/api/v1/partner_events

curl -X POST https://www.vanlo.com/api/v1/partner_events \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
        "partner_event": {
          "tracking_numbers": ["9400111899223333444459"],
          "event_code": "80",
          "event_zip5": "94103",
          "event_date_time": "2026-07-06T14:30:00Z"
        }
      }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::PartnerEvent.create(
  tracking_numbers: ['9400111899223333444459'],
  event_code: '80',
  event_zip5: '94103',
  event_date_time: '2026-07-06T14:30:00Z'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.PartnerEvent.create(
  tracking_numbers=['9400111899223333444459'],
  event_code='80',
  event_zip5='94103',
  event_date_time='2026-07-06T14:30:00Z'
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$partner_event = \Vanlo\PartnerEvent::create(array(
  'tracking_numbers' => array('9400111899223333444459'),
  'event_code' => '80',
  'event_zip5' => '94103',
  'event_date_time' => '2026-07-06T14:30:00Z'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

var parameters = new Dictionary<string, object>() {
    { "tracking_numbers", new List<string>() { "9400111899223333444459" } },
    { "event_code", "80" },
    { "event_zip5", "94103" },
    { "event_date_time", "2026-07-06T14:30:00Z" }
};

PartnerEvent partnerEvent = PartnerEvent.Create(parameters);

Submits an event for one or more of your tracking codes. Each tracking code you pass is resolved to one of your shipments and reported to the USPS.

Only USPS shipments purchased through Vanlo can be reported. Tracking codes that are not eligible - such as an unrecognized code, another carrier's shipment, or a USPS label not bought through Vanlo - are skipped rather than causing the whole request to fail. If none of the supplied tracking codes match a shipment on your account, the request returns an error (see below). Duplicate and blank tracking codes are ignored.

Most events default their scan location and time to the shipment's label data. Physical handling events (codes 80-87) happen at the partner rather than at label creation, so they require you to supply the scan ZIP (event_zip5) and timestamp (event_date_time).

Parameters

Parameter Type Specification
tracking_numbers string[] Required. One or more tracking codes to report the event for. Must contain at least one value. Duplicates and blanks are ignored
event_code string The event being reported (default: "GX"). See Event Codes below
event_zip5 string 5-digit ZIP where the event occurred. Required for physical handling events (80-87). For other events it defaults to the shipment's origin (from-address) ZIP
event_date_time string Timestamp the event occurred, in ISO 8601 (e.g. "2026-07-03T12:00:00Z"). Must be a valid timestamp. Required for physical handling events (80-87). For other events it defaults to the shipment's label timestamp

Event Codes

Code Description
GX Label Created (default)
AL Acceptance / label event
80 Picked up by shipping partner
81 Arrived shipping partner facility
82 Departed shipping partner facility
83 Tendered to Postal Service
84 Arrived agent facility
85 Departed agent facility
86 Delivered by Agent to Merchant
87 Final Disposition by Agent
89 Pre-Shipment Notification, Order Received by Merchant

Codes 84-87 are for use with Parcel Returns Service only.

Codes 80-87 are physical handling scans, so they require event_zip5 and event_date_time. Supplying any other event code returns an UNPROCESSABLE_ENTITY error listing the supported codes.

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "event_zip5",
        "message": "is required for physical handling events (80-87)"
      }
    ]
  }
}

Response for UNPROCESSABLE_ENTITY:

{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "No shipments found for: 9400111899223333444459. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns HTTP 202 Accepted with an empty body. The event is reported to the USPS shortly after the response, and retried automatically if the USPS is unavailable - an accepted event never needs to be re-submitted.

Because ineligible tracking codes are skipped, a 202 Accepted confirms that your request was accepted, not that every tracking code you sent was reported.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 tracking_numbers is empty, event_date_time is not a valid timestamp, or a physical handling event (80-87) is missing event_zip5 or event_date_time. Field-level details are in error.errors
UNPROCESSABLE_ENTITY 422 The event_code is not supported, or none of the supplied tracking codes matched a shipment on your account

Webhooks

Webhook Object

A Webhook:

{
  "id": "hook_...",
  "object": "Webhook",
  "url": "https://example.com/vanlo-webhook",
  "webhook_secret": "whsec_8f2c41d7",
  "disabled_at": null
}

A URL that receives an Event by HTTP POST whenever one of your objects changes. Event Types lists what each event carries.

Parameter Type Specification
id string Unique identifier, begins with "hook_"
object string "Webhook"
url string The URL that webhook notifications are sent to
webhook_secret string The secret Vanlo signs each delivery with, in the X-Hmac-Signature header, or null
disabled_at datetime The time the webhook was disabled, or null if enabled

Create a Webhook

POST/api/v1/webhooks

curl -X POST https://www.vanlo.com/api/v1/webhooks \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "webhook": {
        "url": "https://example.com/vanlo-webhook",
        "webhook_secret": "whsec_8f2c41d7"
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

webhook = Vanlo::Webhook.create(
  url: 'https://example.com/vanlo-webhook',
  webhook_secret: 'whsec_8f2c41d7'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

webhook = vanlo.Webhook.create(
  url="https://example.com/vanlo-webhook",
  webhook_secret="whsec_8f2c41d7"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$webhook = \Vanlo\Webhook::create(array(
  'url' => 'https://example.com/vanlo-webhook',
  'webhook_secret' => 'whsec_8f2c41d7'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Webhook webhook = Webhook.Create(new Dictionary<string, object>() {
    { "url", "https://example.com/vanlo-webhook" },
    { "webhook_secret", "whsec_8f2c41d7" }
});

Registers a URL to receive events. Registering a URL you already have re-enables it instead of adding another.

Parameters

Parameter Type Specification
urlrequired string The URL to receive webhook notifications
webhook_secret string A secret Vanlo signs each delivery with, in the X-Hmac-Signature header

Returns

Response for BAD_REQUEST:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      {
        "field": "url",
        "message": "is missing"
      }
    ]
  }
}

Returns the Webhook.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
BAD_REQUEST 400 url is missing or not a valid URL, or your account already has the most webhooks it may hold. error.errors names the field.

List Webhooks

GET/api/v1/webhooks

curl https://www.vanlo.com/api/v1/webhooks \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Webhook.all
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

webhooks = vanlo.Webhook.all()
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$webhooks = \Vanlo\Webhook::all();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

List<Webhook> webhooks = Webhook.List();

Lists every webhook on your account, in one unpaginated array.

Parameters

This call takes no parameters.

Returns

Response:

[
  {
    "id": "hook_...",
    "object": "Webhook",
    "url": "https://example.com/vanlo-webhook",
    "webhook_secret": "whsec_8f2c41d7",
    "disabled_at": null
  }
]

Returns an array of Webhook.

On failure it returns one of the common errors; this call has none of its own.

Retrieve a Webhook

GET/api/v1/webhooks/:id

curl https://www.vanlo.com/api/v1/webhooks/hook_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Webhook.retrieve('hook_...')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Webhook.retrieve('hook...')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$webhook = \Vanlo\Webhook::retrieve("hook_...");
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Webhook webhook = Webhook.Retrieve("hook_...");

Retrieves a webhook by its id.

Parameters

Parameter Type Specification
id string Unique identifier of the webhook

Returns

Response:

{
  "id": "hook_...",
  "object": "Webhook",
  "url": "https://example.com/vanlo-webhook",
  "webhook_secret": "whsec_8f2c41d7",
  "disabled_at": null
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Webhook.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No webhook of yours has this id.

Update a Webhook

PATCH/api/v1/webhooks/:id

curl -X PATCH https://www.vanlo.com/api/v1/webhooks/hook_... \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
      "webhook": {
        "webhook_secret": "whsec_3b9e07a1"
      }
    }'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

webhook = Vanlo::Webhook.retrieve('hook_...')
webhook.update(webhook_secret: 'whsec_3b9e07a1')
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

webhook = vanlo.Webhook.retrieve('hook_...')
webhook.update(webhook_secret='whsec_3b9e07a1')
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$webhook = \Vanlo\Webhook::retrieve('hook_...');
$webhook->update(array('webhook_secret' => 'whsec_3b9e07a1'));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Webhook webhook = Webhook.Retrieve("hook_...");
webhook.Update(new Dictionary<string, object>() {
    { "webhook_secret", "whsec_3b9e07a1" }
});

Re-enables a disabled webhook, and replaces its webhook_secret when one is sent. PUT works too.

Parameters

Parameter Type Specification
id string Unique identifier of the webhook
webhook_secret string A new secret to sign deliveries with, or null to stop signing them. Without it the stored secret is kept

Returns

Response for PARAMETER.REQUIRED:

{
  "error": {
    "code": "PARAMETER.REQUIRED",
    "message": "Missing required parameter: webhook. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns the Webhook, enabled.

On failure it returns an Error instead. These are the errors specific to this call, on top of the common errors.

Code Status Trigger
PARAMETER.REQUIRED 422 The webhook object is missing or empty.
NOT_FOUND 404 No webhook of yours has this id.

Delete a Webhook

DELETE/api/v1/webhooks/:id

curl -X DELETE https://www.vanlo.com/api/v1/webhooks/hook_... \
  -H 'Authorization: Bearer VANLO_API_KEY'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

webhook = Vanlo::Webhook.retrieve('hook_...')
webhook.delete
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

webhook = vanlo.Webhook.retrieve('hook_...')
webhook.delete()
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$webhook->delete();
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

Webhook webhook = Webhook.Retrieve("hook_...");
webhook.Destroy();

Deletes a webhook, so it receives no further events.

Parameters

Parameter Type Specification
id string Unique identifier of the webhook

Returns

Response for NOT_FOUND:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource could not be found. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": []
  }
}

Returns an empty object.

On failure it returns an Error instead. This is the error specific to this call, on top of the common errors.

Code Status Trigger
NOT_FOUND 404 No webhook of yours has this id.

Events

Event Object

An Event delivered to a webhook:

{
  "id": "evt_...",
  "object": "Event",
  "description": "tracker.updated",
  "pending_urls": [
    "https://example.com/vanlo-webhook"
  ],
  "completed_urls": [],
  "failed_urls": [],
  "result": {
    "id": "trk_...",
    "object": "Tracker",
    "tracking_code": "9405500106024190341287",
    "status": "in_transit",
    "status_detail": "in_transit",
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-21T19:20:13Z",
    "signed_by": null,
    "weight": 32.0,
    "est_delivery_date": "2026-10-23T00:00:00Z",
    "pod_urls": null,
    "shipment_id": "shp_...",
    "carrier": "USPS",
    "tracking_details": [
      {
        "object": "TrackingDetail",
        "message": "Shipping Label Created, USPS Awaiting Item",
        "description": "",
        "status": "pre_transit",
        "status_detail": "label_created",
        "datetime": "2026-10-20T15:06:42Z",
        "source": "USPS",
        "carrier_code": "GX",
        "tracking_location": {
          "object": "TrackingLocation",
          "city": "SAN FRANCISCO",
          "state": "CA",
          "country": "US",
          "zip": "94104"
        }
      },
      {
        "object": "TrackingDetail",
        "message": "Accepted at USPS Origin Facility",
        "description": "",
        "status": "in_transit",
        "status_detail": "arrived_at_facility",
        "datetime": "2026-10-20T23:41:00Z",
        "source": "USPS",
        "carrier_code": "OA",
        "tracking_location": {
          "object": "TrackingLocation",
          "city": "SAN FRANCISCO",
          "state": "CA",
          "country": "US",
          "zip": "94188"
        }
      },
      {
        "object": "TrackingDetail",
        "message": "Arrived at USPS Regional Origin Facility",
        "description": "",
        "status": "in_transit",
        "status_detail": "arrived_at_facility",
        "datetime": "2026-10-21T03:12:00Z",
        "source": "USPS",
        "carrier_code": "10",
        "tracking_location": {
          "object": "TrackingLocation",
          "city": "SAN FRANCISCO",
          "state": "CA",
          "country": "US",
          "zip": "94128"
        }
      },
      {
        "object": "TrackingDetail",
        "message": "In Transit to Next Facility",
        "description": "",
        "status": "in_transit",
        "status_detail": "in_transit",
        "datetime": "2026-10-21T19:05:00Z",
        "source": "USPS",
        "carrier_code": "NT",
        "tracking_location": {
          "object": "TrackingLocation",
          "city": null,
          "state": null,
          "country": "US",
          "zip": null
        }
      }
    ],
    "carrier_detail": {
      "object": "CarrierDetail",
      "service": "Priority",
      "container_type": null,
      "est_delivery_date_local": "2026-10-23",
      "est_delivery_time_local": null,
      "origin_location": "SAN FRANCISCO CA, 94104",
      "origin_tracking_location": {
        "object": "TrackingLocation",
        "city": "SAN FRANCISCO",
        "state": "CA",
        "country": "US",
        "zip": "94104"
      },
      "destination_location": "NEW YORK NY, 10019",
      "destination_tracking_location": {
        "object": "TrackingLocation",
        "city": "NEW YORK",
        "state": "NY",
        "country": "US",
        "zip": "10019"
      },
      "guaranteed_delivery_date": null,
      "alternate_identifier": null,
      "initial_delivery_attempt": null
    },
    "is_return": false,
    "finalized": false,
    "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
  },
  "created_at": "2026-10-21T19:20:14Z",
  "updated_at": "2026-10-21T19:20:14Z"
}

An Event records something that happened on your account, such as a tracker status change, and is what your webhooks receive.

Parameter Type Specification
id string Unique identifier, begins with "evt_"
object string "Event"
description string Event type descriptor, e.g. "tracker.updated" or "batch.updated"
pending_urls string[] Array of webhook URLs that have not yet received this event
completed_urls string[] Array of webhook URLs that have successfully received this event
failed_urls string[] Array of webhook URLs that failed to receive this event
result object The payload, which depends on the event type. Event Types lists each one
created_at datetime When the event was created
updated_at datetime When the event was last updated

List Events

GET/api/v1/events

curl -G https://www.vanlo.com/api/v1/events \
  -H 'Authorization: Bearer VANLO_API_KEY' \
  -d 'page_size=5' \
  -d 'start_datetime=2026-10-21T00:00:00Z'
require 'vanlo'
Vanlo.api_key = 'VANLO_API_KEY'

Vanlo::Event.all(
  page_size: 5,
  start_datetime: '2026-10-21T00:00:00Z'
)
import vanlo
vanlo.api_key = 'VANLO_API_KEY'

vanlo.Event.all(
  page_size=5,
  start_datetime="2026-10-21T00:00:00Z"
)
require_once('/path/to/lib/vanlo.php');
\Vanlo\Vanlo::setApiKey('VANLO_API_KEY');

$events = \Vanlo\Event::all(array(
  'page_size' => 5,
  'start_datetime' => '2026-10-21T00:00:00Z'
));
using Vanlo;
ClientManager.SetCurrent("VANLO_API_KEY");

EventList eventList = Event.List(new Dictionary<string, object>() {
    { "page_size", 5 },
    { "start_datetime", "2026-10-21T00:00:00Z" }
});

Lists the events sent to your webhooks, a page at a time, to debug a delivery or replay a missed one. Pass before_id or after_id to say where the next page begins.

Parameters

Parameter Type Specification
before_id string Return events created before this id
after_id string Return events created after this id
start_datetime datetime Only return events created after this timestamp
end_datetime datetime Only return events created before this timestamp
page_size integer Number of events to return per page (default 20, max 100)

Returns

Response:

{
  "events": [
    {
      "id": "evt_...",
      "object": "Event",
      "description": "tracker.updated",
      "pending_urls": [],
      "completed_urls": [
        "https://example.com/vanlo-webhook"
      ],
      "failed_urls": [],
      "result": {
        "id": "trk_...",
        "object": "Tracker",
        "tracking_code": "9405500106024190341287",
        "status": "in_transit",
        "status_detail": "in_transit",
        "created_at": "2026-10-20T15:06:40Z",
        "updated_at": "2026-10-21T19:20:13Z",
        "signed_by": null,
        "weight": 32.0,
        "est_delivery_date": "2026-10-23T00:00:00Z",
        "pod_urls": null,
        "shipment_id": "shp_...",
        "carrier": "USPS",
        "tracking_details": [
          {
            "object": "TrackingDetail",
            "message": "Shipping Label Created, USPS Awaiting Item",
            "description": "",
            "status": "pre_transit",
            "status_detail": "label_created",
            "datetime": "2026-10-20T15:06:42Z",
            "source": "USPS",
            "carrier_code": "GX",
            "tracking_location": {
              "object": "TrackingLocation",
              "city": "SAN FRANCISCO",
              "state": "CA",
              "country": "US",
              "zip": "94104"
            }
          },
          {
            "object": "TrackingDetail",
            "message": "Accepted at USPS Origin Facility",
            "description": "",
            "status": "in_transit",
            "status_detail": "arrived_at_facility",
            "datetime": "2026-10-20T23:41:00Z",
            "source": "USPS",
            "carrier_code": "OA",
            "tracking_location": {
              "object": "TrackingLocation",
              "city": "SAN FRANCISCO",
              "state": "CA",
              "country": "US",
              "zip": "94188"
            }
          },
          {
            "object": "TrackingDetail",
            "message": "Arrived at USPS Regional Origin Facility",
            "description": "",
            "status": "in_transit",
            "status_detail": "arrived_at_facility",
            "datetime": "2026-10-21T03:12:00Z",
            "source": "USPS",
            "carrier_code": "10",
            "tracking_location": {
              "object": "TrackingLocation",
              "city": "SAN FRANCISCO",
              "state": "CA",
              "country": "US",
              "zip": "94128"
            }
          },
          {
            "object": "TrackingDetail",
            "message": "In Transit to Next Facility",
            "description": "",
            "status": "in_transit",
            "status_detail": "in_transit",
            "datetime": "2026-10-21T19:05:00Z",
            "source": "USPS",
            "carrier_code": "NT",
            "tracking_location": {
              "object": "TrackingLocation",
              "city": null,
              "state": null,
              "country": "US",
              "zip": null
            }
          }
        ],
        "carrier_detail": {
          "object": "CarrierDetail",
          "service": "Priority",
          "container_type": null,
          "est_delivery_date_local": "2026-10-23",
          "est_delivery_time_local": null,
          "origin_location": "SAN FRANCISCO CA, 94104",
          "origin_tracking_location": {
            "object": "TrackingLocation",
            "city": "SAN FRANCISCO",
            "state": "CA",
            "country": "US",
            "zip": "94104"
          },
          "destination_location": "NEW YORK NY, 10019",
          "destination_tracking_location": {
            "object": "TrackingLocation",
            "city": "NEW YORK",
            "state": "NY",
            "country": "US",
            "zip": "10019"
          },
          "guaranteed_delivery_date": null,
          "alternate_identifier": null,
          "initial_delivery_attempt": null
        },
        "is_return": false,
        "finalized": false,
        "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
      },
      "created_at": "2026-10-21T19:20:14Z",
      "updated_at": "2026-10-21T19:20:15Z"
    }
  ],
  "has_more": true
}

Returns an object with events, an array of Event, and has_more, which says whether another page exists. Each result is the payload delivered to your webhooks.

On failure it returns one of the common errors; this call has none of its own.

Event Types

Each event type returns a specific set of data in the result field of the webhook event. The events below are the v1 events Vanlo sends, grouped by the object they describe.

Delivery, retry, and authentication are the same for every event - see the Webhooks Guide for those details. The sections below document only the result payload of each event.

Batch Events

batch.created

Example result payload:

{
  "id": "batch_...",
  "object": "Batch",
  "label_url": null,
  "num_shipments": 2,
  "state": "created",
  "scan_form": null,
  "shipments": [
    {
      "id": "shp_...",
      "batch_status": "created",
      "batch_message": null,
      "tracking_code": null
    },
    {
      "id": "shp_...",
      "batch_status": "created",
      "batch_message": null,
      "tracking_code": null
    }
  ],
  "status": {
    "created": 2,
    "queued_for_purchase": 0,
    "creation_failed": 0,
    "postage_purchased": 0,
    "postage_purchase_failed": 0
  },
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:04:12Z"
}

Sent when a new batch is created. The result is a Batch object.

batch.updated

Example result payload:

{
  "id": "batch_...",
  "object": "Batch",
  "label_url": null,
  "num_shipments": 2,
  "state": "purchased",
  "scan_form": null,
  "shipments": [
    {
      "id": "shp_...",
      "batch_status": "postage_purchased",
      "batch_message": null,
      "tracking_code": "9405500106024190341287"
    },
    {
      "id": "shp_...",
      "batch_status": "postage_purchased",
      "batch_message": null,
      "tracking_code": "9405500106024190341294"
    }
  ],
  "status": {
    "created": 0,
    "queued_for_purchase": 0,
    "creation_failed": 0,
    "postage_purchased": 2,
    "postage_purchase_failed": 0
  },
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-20T15:06:40Z"
}

Sent when a batch purchase finishes, with state purchased or purchase_failed, and when its combined label is generated. The result is the same Batch object as batch.created.

Tracker Events

tracker.updated

Example result payload:

{
  "id": "trk_...",
  "object": "Tracker",
  "tracking_code": "9405500106024190341287",
  "status": "in_transit",
  "status_detail": "in_transit",
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-21T19:20:13Z",
  "signed_by": null,
  "weight": 32.0,
  "est_delivery_date": "2026-10-23T00:00:00Z",
  "pod_urls": null,
  "shipment_id": "shp_...",
  "carrier": "USPS",
  "tracking_details": [
    {
      "object": "TrackingDetail",
      "message": "Shipping Label Created, USPS Awaiting Item",
      "description": "",
      "status": "pre_transit",
      "status_detail": "label_created",
      "datetime": "2026-10-20T15:06:42Z",
      "source": "USPS",
      "carrier_code": "GX",
      "tracking_location": {
        "object": "TrackingLocation",
        "city": "SAN FRANCISCO",
        "state": "CA",
        "country": "US",
        "zip": "94104"
      }
    },
    {
      "object": "TrackingDetail",
      "message": "Accepted at USPS Origin Facility",
      "description": "",
      "status": "in_transit",
      "status_detail": "arrived_at_facility",
      "datetime": "2026-10-20T23:41:00Z",
      "source": "USPS",
      "carrier_code": "OA",
      "tracking_location": {
        "object": "TrackingLocation",
        "city": "SAN FRANCISCO",
        "state": "CA",
        "country": "US",
        "zip": "94188"
      }
    },
    {
      "object": "TrackingDetail",
      "message": "Arrived at USPS Regional Origin Facility",
      "description": "",
      "status": "in_transit",
      "status_detail": "arrived_at_facility",
      "datetime": "2026-10-21T03:12:00Z",
      "source": "USPS",
      "carrier_code": "10",
      "tracking_location": {
        "object": "TrackingLocation",
        "city": "SAN FRANCISCO",
        "state": "CA",
        "country": "US",
        "zip": "94128"
      }
    },
    {
      "object": "TrackingDetail",
      "message": "In Transit to Next Facility",
      "description": "",
      "status": "in_transit",
      "status_detail": "in_transit",
      "datetime": "2026-10-21T19:05:00Z",
      "source": "USPS",
      "carrier_code": "NT",
      "tracking_location": {
        "object": "TrackingLocation",
        "city": null,
        "state": null,
        "country": "US",
        "zip": null
      }
    }
  ],
  "carrier_detail": {
    "object": "CarrierDetail",
    "service": "Priority",
    "container_type": null,
    "est_delivery_date_local": "2026-10-23",
    "est_delivery_time_local": null,
    "origin_location": "SAN FRANCISCO CA, 94104",
    "origin_tracking_location": {
      "object": "TrackingLocation",
      "city": "SAN FRANCISCO",
      "state": "CA",
      "country": "US",
      "zip": "94104"
    },
    "destination_location": "NEW YORK NY, 10019",
    "destination_tracking_location": {
      "object": "TrackingLocation",
      "city": "NEW YORK",
      "state": "NY",
      "country": "US",
      "zip": "10019"
    },
    "guaranteed_delivery_date": null,
    "alternate_identifier": null,
    "initial_delivery_attempt": null
  },
  "is_return": false,
  "finalized": false,
  "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
}

Sent whenever a tracker receives new tracking information from the carrier. The result is a Tracker object.

Parameter Type Specification
id string Unique identifier of the tracker, begins with "trk_"
object string "Tracker"
status string Current tracking status: "unknown", "pre_transit", "in_transit", "out_for_delivery", "available_for_pickup", "delivered", "return_to_sender", "failure", "cancelled", or "error"
carrier string Name of the carrier handling the shipment
tracking_code string The tracking code provided by the carrier
shipment_id string Identifier of the associated shipment, if any
status_detail string The carrier's finer-grained status, such as "arrived_at_facility", when it gives one
tracking_details TrackingDetails[] Every scan so far. Each also carries description, status_detail, carrier_code and its TrackingLocation in tracking_location
carrier_detail CarrierDetail Associated CarrierDetail object, when the carrier supplies one
pod_urls string[] Proof-of-delivery image URLs, if any
is_return boolean Whether the package is being returned to the sender, when the carrier says
finalized boolean Whether the tracker has reached its last status, when the carrier says
public_url string URL to a publicly-accessible tracking page
est_delivery_date datetime Estimated delivery date, if available
signed_by string Name of the person who signed for the package, if available
weight float Weight of the package, if available
created_at datetime When the tracker was created
updated_at datetime When the tracker was last updated

tracker.detail.created

Example result payload:

{
  "message": "In Transit to Next Facility",
  "status": "in_transit",
  "datetime": "2026-10-21 19:05:00",
  "location": {
    "city": "SAN FRANCISCO",
    "state": "CA",
    "country": "US",
    "zip": "94128"
  },
  "created_at": "2026-10-21 19:20:13",
  "tracker_id": "trk_...",
  "tracking_code": "9405500106024190341287"
}

Sent for each new tracking detail (carrier scan) added to a tracker. The result is a single tracking detail, with the parent tracker's tracker_id and tracking_code attached.

Parameter Type Specification
status string Tracking status reported by this scan
message string Human-readable description of the scan
datetime string When the scan occurred, as "YYYY-MM-DD HH:MM:SS" in the time the carrier reported, without a zone
location object Scan location: city, state, country, zip
pod_urls string[] Proof-of-delivery image URLs. Present only when there are some
created_at string When Vanlo recorded the scan, in UTC as "YYYY-MM-DD HH:MM:SS"
tracker_id string Identifier of the parent tracker, begins with "trk_"
tracking_code string The tracking code of the parent tracker

Refund Events

refund.successful

Example result payload:

{
  "id": "rfnd_...",
  "object": "Refund",
  "status": "refunded",
  "shipment_id": "shp_...",
  "created_at": "2026-10-20T15:04:12Z",
  "updated_at": "2026-10-21T16:02:44Z",
  "carrier": "USPS",
  "tracking_code": "9405500106024190341287"
}

Sent when a refund request for a shipment is approved by the carrier. The result is a Refund object.

Parameter Type Specification
id string Unique identifier of the refund, begins with "rfnd_"
object string "Refund"
status string "refunded"
shipment_id string Identifier of the refunded shipment, begins with "shp_"
carrier string Name of the carrier that issued the refund
tracking_code string The tracking code of the refunded shipment
created_at datetime When the refund was created
updated_at datetime When the refund was last updated

Insurance Events

insurance.purchased

Example result payload:

{
  "id": "ins_...",
  "object": "Insurance",
  "reference": "vanlo_shp_...",
  "amount": "150.00000",
  "provider": "shipsurance",
  "provider_id": "7720394",
  "status": "purchased",
  "messages": [],
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-20T15:06:40Z",
  "shipment_id": "shp_...",
  "tracking_code": "9405500106024190341287",
  "tracker": {
    "id": "trk_...",
    "object": "Tracker",
    "shipment_id": "shp_...",
    "tracking_details": [],
    "created_at": "2026-10-20T15:06:40Z",
    "updated_at": "2026-10-20T15:06:40Z",
    "status": "unknown",
    "carrier": "USPS",
    "tracking_code": "9405500106024190341287",
    "public_url": "https://tracking.parcelshop.com/9405500106024190341287"
  },
  "from_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "to_address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "John Doe",
    "company": null,
    "street1": "148 W 51st St",
    "street2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10019",
    "country": "US",
    "phone": "2125550199",
    "email": "john.doe@example.com",
    "residential": true,
    "verifications": null
  },
  "fee": {
    "amount": "1.50000"
  }
}

Sent when insurance is successfully purchased for a shipment. The result is an Insurance object.

Parameter Type Specification
id string Unique identifier of the insurance, begins with "ins_"
object string "Insurance"
reference string The policy reference: vanlo_ and the shipment id
amount string Insured value of the shipment
provider string Name of the insurance provider
provider_id string The provider's identifier for the policy
status string Current status of the insurance
messages string[] Provider messages, if any
shipment_id string Identifier of the insured shipment, begins with "shp_"
tracking_code string The tracking code of the insured shipment
tracker Tracker Associated Tracker object, if available
from_address Address Origin address, if available
to_address Address Destination address, if available
fee object Insurance fee: amount
created_at datetime When the insurance was created
updated_at datetime When the insurance was last updated

Payment Events

payment.created

Example result payload:

{
  "id": "paylog_...",
  "object": "PaymentLog",
  "amount": "25.00",
  "balance": "150.00",
  "status": "pending",
  "source_type": "bank_account",
  "target_type": "vanlo_stripe",
  "charge_type": "recharge",
  "created_at": "2026-10-20T14:02:51Z"
}

Sent when a payment (account recharge) is initiated. The result is a PaymentLog object.

Parameter Type Specification
id string Unique identifier of the payment log, begins with "paylog_"
object string "PaymentLog"
amount string Charged amount
balance string Account balance after the payment, if available
status string Payment status: "pending", "completed", or "failed"
source_type string Funding source: "bank_account" or "credit_card"
target_type string "vanlo_stripe"
charge_type string "recharge"
created_at datetime When the payment was created

payment.completed

Example result payload:

{
  "id": "paylog_...",
  "object": "PaymentLog",
  "amount": "25.00",
  "balance": "175.00",
  "status": "completed",
  "source_type": "bank_account",
  "target_type": "vanlo_stripe",
  "charge_type": "recharge",
  "created_at": "2026-10-20T14:02:51Z"
}

Sent when a payment clears. The result is the same PaymentLog object as payment.created, with status set to completed.

payment.failed

Example result payload:

{
  "id": "paylog_...",
  "object": "PaymentLog",
  "amount": "25.00",
  "balance": "150.00",
  "status": "failed",
  "source_type": "bank_account",
  "target_type": "vanlo_stripe",
  "charge_type": "recharge",
  "created_at": "2026-10-20T14:02:51Z"
}

Sent when a payment fails. The result is the same PaymentLog object as payment.created, with status set to failed.

Report Events

report.new

Example result payload:

{
  "id": "shprep_...",
  "object": "ShipmentReport",
  "created_at": "2026-10-20T15:30:02Z",
  "updated_at": "2026-10-20T15:30:02Z",
  "start_date": "2026-09-20",
  "end_date": "2026-10-19",
  "status": "new",
  "url": null,
  "url_expires_at": null
}

Sent when a report is requested and starts generating. The result is a Report object.

Parameter Type Specification
id string Unique identifier of the report, with a prefix for its type, such as "shprep_"
object string The report type, e.g. "ShipmentReport" or "PaymentLogReport"
status string "new", "available", or "failed". These are the API's new and generating, ready, and error
start_date date First day covered by the report
end_date date Last day covered by the report
url string Download URL, present once the report is available
url_expires_at datetime When the download URL expires, present once available
created_at datetime When the report was created
updated_at datetime When the report was last updated

report.available

Example result payload:

{
  "id": "shprep_...",
  "object": "ShipmentReport",
  "created_at": "2026-10-20T15:30:02Z",
  "updated_at": "2026-10-20T15:31:47Z",
  "start_date": "2026-09-20",
  "end_date": "2026-10-19",
  "status": "available",
  "url": "https://s3.us-west-2.amazonaws.com/vanlo.com/...?response-content-disposition=attachment%3B%20filename%3D%22shipments-2026-09-20-2026-10-19.csv.zip%22&response-content-type=application%2Fzip&X-Amz-Expires=3600&X-Amz-Signature=...",
  "url_expires_at": "2026-10-20T16:42:10.884Z"
}

Sent when a report has finished generating and is ready to download. The result is the same Report object as report.new, with status set to available and the url populated.

report.failed

Example result payload:

{
  "id": "shprep_...",
  "object": "ShipmentReport",
  "created_at": "2026-10-20T15:30:02Z",
  "updated_at": "2026-10-20T15:31:47Z",
  "start_date": "2026-09-20",
  "end_date": "2026-10-19",
  "status": "failed",
  "url": null,
  "url_expires_at": null
}

Sent when a report fails to generate. The result is the same Report object as report.new, with status set to failed.

Shipment Events

shipment.invoice.created

Example result payload:

{
  "id": "ppshp_...",
  "object": "ShipmentInvoice",
  "status": "processed",
  "shipment_id": "shp_...",
  "label_date": "2026-10-20",
  "tracking_code": "9405500106024190341287",
  "quoted_amount": "11.20",
  "quoted_currency": "USD",
  "initially_paid_amount": "11.20",
  "initially_paid_currency": "USD",
  "initially_paid_payment_log": "paylog_...",
  "adjustment_reason": "weight_correction",
  "adjustment_amount": "4.35",
  "invoice_date": "2026-11-03T09:12:40Z",
  "invoice_type": "adjustment",
  "invoice_amount": "4.35",
  "invoice_currency": "USD",
  "invoice_payment_log": "paylog_...",
  "total_cost": "15.55",
  "carrier_account": "ca_...",
  "carrier": "USPS",
  "claimed_details": {
    "parcel": {
      "weight": 32.0
    },
    "zone": 8
  },
  "captured_details": {
    "parcel": {
      "weight": 56.0
    },
    "zone": 8
  }
}

Sent when a carrier issues a post-purchase adjustment (a corrected charge) for a shipment. The result is a ShipmentInvoice object.

Parameter Type Specification
id string Unique identifier of the invoice, begins with "ppshp_"
object string "ShipmentInvoice"
status string "processed"
shipment_id string Identifier of the adjusted shipment, begins with "shp_"
tracking_code string The tracking code of the adjusted shipment
label_date date Date the label was created
quoted_amount string Amount originally quoted for the shipment
quoted_currency string "USD"
initially_paid_amount string Amount initially paid for the shipment
initially_paid_currency string "USD"
initially_paid_payment_log string Payment log identifier for the initial charge
adjustment_reason string Reason for the adjustment, e.g. "weight_correction"
adjustment_amount string Amount of the adjustment
invoice_date datetime When the adjustment was recorded
invoice_type string "adjustment"
invoice_amount string Amount of the invoice
invoice_currency string "USD"
invoice_payment_log string Payment log identifier for the adjustment charge
total_cost string Total cost after the adjustment
carrier_account string Identifier of the carrier account used
carrier string Name of the carrier
claimed_details object What the label was bought with, such as { "parcel": { "weight": 32.0 }, "zone": 8 }
captured_details object What the carrier measured, in the same shape as claimed_details

Scan Form Events

scan_form.updated

Example result payload:

{
  "id": "sf_...",
  "object": "ScanForm",
  "tracking_codes": [
    "9405500106024190341287",
    "9405500106024190341294"
  ],
  "address": {
    "id": "adr_...",
    "object": "Address",
    "created_at": "2026-10-20T15:04:11Z",
    "updated_at": "2026-10-20T15:04:11Z",
    "name": "Jane Smith",
    "company": "Acme Goods",
    "street1": "417 Montgomery St",
    "street2": "Floor 5",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4155550100",
    "email": "shipping@acme.example",
    "residential": null,
    "verifications": null
  },
  "message": null,
  "batch_id": null,
  "form": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp...",
  "reference": "order-1042",
  "status": "ready",
  "form_url": "https://www.vanlo.com/rails/active_storage/blobs/proxy/.../scan_form.pdf",
  "created_at": "2026-10-20T15:06:40Z",
  "updated_at": "2026-10-20T15:06:40Z"
}

Sent when a scan form is created or its status changes. The result is a ScanForm object.

Parameter Type Specification
id string Unique identifier of the scan form, begins with "sf_"
object string "ScanForm"
status string Current status of the scan form
tracking_codes string[] Tracking codes included on the form
address Address Origin address, if available
message string Error message, if the form failed
warnings object Shipments left off a ready scan form: each shipment id maps to a list of the reasons. Present only when there are some
batch_id string Identifier of the associated batch, if any, begins with "batch_"
reference string Your reference for the scan form, if provided
form_url string URL of the generated scan form document
created_at datetime When the scan form was created
updated_at datetime When the scan form was last updated

Errors

The Vanlo API answers every failed request with a standard HTTP status and an error body. The status gives the class of problem; error.code says exactly what went wrong.

Error Object

A Create a Shipment request without to_address:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request, please check params and retry. Request ID: 6f1c2e4a-9b3d-4e8f-a1c2-5d7e8f9a0b1c",
    "errors": [
      { "field": "to_address", "message": "is missing" }
    ]
  }
}

Every error response holds a single error object.

Parameter Type Specification
code string Stable, machine-readable code such as BAD_REQUEST. Handle errors by this value.
message string Human-readable description, ending with the request ID for support. The wording can change, so never match on it.
errors object[] One { field, message } entry for each field that was missing or invalid.
details object Extra hints, present only where the endpoint sets them, such as the scan-form ids returned on a scan-form scoping error.

A few errors also return the affected resource, with its fields at the top level of the body next to error. A 409 CONFLICT on a shipment custom_id does this, as shown under Create a Shipment.

Client errors

A 4xx status means the request is the problem, and the same request fails the same way again, so fix it before retrying. Any endpoint can return these errors. One specific to a single call, such as PAYMENT_REQUIRED when buying a label, is listed under that call's Returns.

CARRIER_SERVICE_UNAVAILABLE, LOCKED and TOO_MANY_REQUESTS clear on their own. Retry them with backoff, waiting the Retry-After header or error.details.retry_after when the response carries one.

Code Status When it happens
BAD_REQUEST 400 The request is malformed and cannot be parsed or routed.
UNAUTHORIZED 401 The API key is missing or invalid.
FORBIDDEN 403 The key lacks permission for this resource.
IP_ADDRESS.FORBIDDEN 403 The request comes from an IP address that is not on the key's allowlist.
NOT_FOUND 404 The id or path does not exist.
NOT_ACCEPTABLE 406 The Accept header asks for a representation the API cannot return.
CONFLICT 409 The same entity is created or updated twice at once, or a custom_id shipment can no longer change: its label is bought or being bought, its 72-hour window has passed, or, on Create an Order, it already belongs to one.
UNPROCESSABLE_ENTITY 422 The request is understood but semantically invalid.
PARAMETER.FORBIDDEN 422 The request sends a field it may not set.
INVALID_PARAMETERS 422 One or more parameters are invalid; error.errors lists them.
PARAMETER.REQUIRED 422 A required field is missing; error.errors names it.
PARAMETER.INVALID_TYPE 422 A field has the wrong type.
CARRIER_SERVICE_UNAVAILABLE 424 The carrier cannot be used right now: it failed the purchase, or Vanlo paused calls to it after repeated timeouts and will resume on its own.
LOCKED 429 Another operation holds the lock, such as a burst of scan-form requests. On a purchase, Vanlo is still confirming an earlier purchase of that shipment with the carrier.
TOO_MANY_REQUESTS 429 More label purchases are in flight for your account than Vanlo will carry. Other endpoints use this code for their own limits, listed under their Returns.

Server errors

A 5xx status is not caused by the request and is usually safe to retry with backoff. If INTERNAL_SERVER_ERROR persists, contact support@vanlo.com.

Code Status When it happens
INTERNAL_SERVER_ERROR 500 An unexpected error on Vanlo's side.
MAINTENANCE 503 Scheduled maintenance.
CARRIER_RESPONSE_UNREADABLE 503 The carrier answered a label purchase with success, but Vanlo could not read the reply, so the label may exist.
TIMEOUT_EXCEEDED 504 The request used up its 60-second budget, counted from its arrival, possibly before a carrier was called. On a purchase, a label may still be produced afterwards.
CARRIER_UPSTREAM_TIMEOUT 504 The carrier gave no usable answer: it passed the 30-second limit, did not reply, or returned a gateway error. On a refund, an unreadable success reply also returns this.