upsdeveloper

UPS Shipping API Integration: Developer Guide

A comprehensive developer guide to integrating with the UPS Shipping API — authentication, rate shopping, label generation, tracking, address validation, and production deployment best practices.

July 17, 202512 min read
UPS Shipping API Integration: Developer Guide

UPS Shipping API Integration: Developer Guide

Integrating with the UPS API allows your application to programmatically create shipments, generate labels, track packages, validate addresses, and access the full range of UPS services. This developer guide walks through every aspect of the UPS API integration process, from authentication to production deployment, with practical code examples and best practices.

UPS API Overview

UPS offers a comprehensive suite of RESTful APIs through the UPS Developer Kit. In 2024, UPS completed a major migration from their legacy XML-based APIs to modern OAuth 2.0 REST APIs. All new integrations should use the REST APIs.

Available APIs

APIPurposeKey Endpoints
Rating APIGet shipping rates and transit times/api/rating/v2403/rate
Shipping APICreate shipments and generate labels/api/shipments/v2409/ship
Tracking APITrack packages and get delivery status/api/track/v1/details
Address Validation APIValidate and correct addresses/api/addressvalidation/v2/validate
Time in Transit APIGet estimated delivery dates/api/deliverytimeintransit/v1/estimateddelivery
Locator APIFind UPS locations and Access Points/api/locations/v2/search/availabilities
Pickup APISchedule package pickups/api/pickupcreation/v1/pickup
Void APICancel shipments and void labels/api/shipments/v2409/void/cancel

API Environments

EnvironmentBase URLPurpose
Sandbox (CIE)https://wwwcie.ups.comTesting and development
Productionhttps://onlinetools.ups.comLive production traffic

Authentication: OAuth 2.0

All UPS REST APIs use OAuth 2.0 client credentials flow for authentication.

Step 1: Create a UPS Developer Account

  • Go to https://developer.ups.com
  • Register for a developer account
  • Create a new application
  • Note your Client ID and Client Secret
  • Step 2: Obtain an Access Token

    Request an access token from the OAuth endpoint:

    POST https://onlinetools.ups.com/security/v1/oauth/token
    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic {base64(clientId:clientSecret)}

    grant_type=client_credentials

    Response:

    {
      "token_type": "Bearer",
      "issued_at": "1706803200000",
      "client_id": "your_client_id",
      "access_token": "eyJhbGciOi...",
      "expires_in": "14399",
      "status": "approved"
    }
    

    Step 3: Use the Token in API Calls

    Include the access token in the Authorization header of all subsequent API calls:

    Authorization: Bearer eyJhbGciOi...
    

    Token Management Best Practices

    PracticeImplementation
    Cache tokensStore token and expiry; reuse until 5 minutes before expiration
    Handle expiryImplement automatic token refresh logic
    Secure storageNever log or expose tokens; use environment variables
    Rate limitingUPS allows ~250 token requests per day; caching is essential

    Rating API: Getting Shipping Rates

    The Rating API is typically the first API you integrate because it allows you to display shipping costs to customers.

    Basic Rate Request

    POST /api/rating/v2403/rate
    Authorization: Bearer {token}
    Content-Type: application/json
    transId: {unique-transaction-id}

    { "RateRequest": { "Request": { "SubVersion": "2403", "TransactionReference": { "CustomerContext": "order-12345" } }, "Shipment": { "Shipper": { "Name": "Your Business Name", "ShipperNumber": "YOUR_ACCOUNT", "Address": { "AddressLine": ["123 Main St"], "City": "New York", "StateProvinceCode": "NY", "PostalCode": "10001", "CountryCode": "US" } }, "ShipTo": { "Name": "Customer Name", "Address": { "AddressLine": ["456 Oak Ave"], "City": "Los Angeles", "StateProvinceCode": "CA", "PostalCode": "90001", "CountryCode": "US" } }, "ShipFrom": { "Name": "Your Warehouse", "Address": { "AddressLine": ["123 Main St"], "City": "New York", "StateProvinceCode": "NY", "PostalCode": "10001", "CountryCode": "US" } }, "Package": [ { "PackagingType": { "Code": "02", "Description": "Customer Supplied Package" }, "Dimensions": { "UnitOfMeasurement": { "Code": "IN" }, "Length": "12", "Width": "10", "Height": "8" }, "PackageWeight": { "UnitOfMeasurement": { "Code": "LBS" }, "Weight": "5" } } ] } } }

    Rate Response Key Fields

    FieldLocation in ResponseDescription
    Service codeRatedShipment.Service.CodeUPS service identifier
    Total chargesRatedShipment.TotalCharges.MonetaryValueTotal shipping cost
    Billable weightRatedShipment.BillingWeight.WeightActual or DIM weight used for pricing
    Transit daysRatedShipment.GuaranteedDelivery.BusinessDaysInTransitExpected delivery days
    SurchargesRatedShipment.ItemizedCharges[]Fuel, residential, etc.

    UPS Service Codes Reference

    CodeService NameTypical Transit
    01UPS Next Day Air1 business day
    02UPS 2nd Day Air2 business days
    03UPS Ground1–5 business days
    12UPS 3 Day Select3 business days
    13UPS Next Day Air Saver1 business day (end of day)
    14UPS Next Day Air Early AM1 business day (8:00/8:30 AM)
    59UPS 2nd Day Air AM2 business days (AM delivery)

    Shop Rates (Compare All Services)

    To get rates for all available services in one call, use the "Shop" request option:

    {
      "RateRequest": {
        "Request": {
          "RequestOption": "Shop"
        },
        "Shipment": { ... }
      }
    }
    

    This returns an array of RatedShipment objects, one for each available service, sorted by cost.

    Shipping API: Creating Labels

    Once a customer selects a service and confirms their order, use the Shipping API to create the shipment and generate a label.

    Create Shipment Request

    POST /api/shipments/v2409/ship
    Authorization: Bearer {token}
    Content-Type: application/json

    { "ShipmentRequest": { "Request": { "SubVersion": "2409", "TransactionReference": { "CustomerContext": "order-12345" } }, "Shipment": { "Shipper": { "Name": "Your Business", "AttentionName": "Shipping Dept", "ShipperNumber": "YOUR_ACCOUNT", "Phone": { "Number": "2125551234" }, "Address": { "AddressLine": ["123 Main St"], "City": "New York", "StateProvinceCode": "NY", "PostalCode": "10001", "CountryCode": "US" } }, "ShipTo": { "Name": "John Customer", "Phone": { "Number": "3105559876" }, "Address": { "AddressLine": ["456 Oak Ave"], "City": "Los Angeles", "StateProvinceCode": "CA", "PostalCode": "90001", "CountryCode": "US" } }, "PaymentInformation": { "ShipmentCharge": [{ "Type": "01", "BillShipper": { "AccountNumber": "YOUR_ACCOUNT" } }] }, "Service": { "Code": "03", "Description": "UPS Ground" }, "Package": [{ "Packaging": { "Code": "02" }, "Dimensions": { "UnitOfMeasurement": { "Code": "IN" }, "Length": "12", "Width": "10", "Height": "8" }, "PackageWeight": { "UnitOfMeasurement": { "Code": "LBS" }, "Weight": "5" } }] }, "LabelSpecification": { "LabelImageFormat": { "Code": "ZPL" }, "LabelStockSize": { "Height": "6", "Width": "4" } } } }

    Label Format Options

    Format CodeFormatUse Case
    GIFGIF imageWeb display, email labels
    PNGPNG imageHigh-quality printing
    ZPLZebra Printer LanguageThermal label printers
    EPLEltron Printer LanguageOlder thermal printers
    PDFPDF documentStandard laser/inkjet printing

    Response: Tracking Number and Label

    The response contains:

    FieldDescription
    ShipmentIdentificationNumberMaster tracking number for the shipment
    PackageResults[].TrackingNumberIndividual package tracking numbers
    PackageResults[].ShippingLabel.GraphicImageBase64-encoded label image
    ShipmentCharges.TotalChargesActual shipping cost charged

    Tracking API: Package Status

    Single Package Tracking

    GET /api/track/v1/details/{trackingNumber}
    Authorization: Bearer {token}
    transId: {unique-id}
    transactionSrc: your-app-name
    

    Tracking Response Key Fields

    FieldDescription
    currentStatus.typeCurrent status (In Transit, Delivered, etc.)
    currentStatus.codeStatus code (021 = In Transit, 011 = Delivered)
    deliveryDate[].dateActual or estimated delivery date
    activity[]Array of scan events with timestamps and locations
    weightPackage weight as recorded by UPS

    Common Status Codes

    CodeTypeDescription
    003Order ProcessedLabel created, not yet in UPS system
    005ShippedPackage picked up and in transit
    021In TransitPackage moving through UPS network
    011DeliveredPackage delivered
    007ExceptionDelivery exception (weather, address issue, etc.)

    Address Validation API

    Validating addresses before creating shipments prevents failed deliveries and costly address corrections.

    Validation Request

    POST /api/addressvalidation/v2/validate
    Authorization: Bearer {token}
    Content-Type: application/json

    { "XAVRequest": { "AddressKeyFormat": { "AddressLine": ["456 Oak Avenue"], "PoliticalDivision2": "Los Angeles", "PoliticalDivision1": "CA", "PostcodePrimaryLow": "90001", "CountryCode": "US" } } }

    Response Classification

    IndicatorMeaningAction
    ValidAddress is valid and deliverableProceed with shipment
    AmbiguousMultiple matching addresses foundPresent candidates to user
    InvalidAddress not found or not deliverableRequest correction from customer

    Residential Indicator

    The Address Validation API also returns whether the address is residential or commercial:

    ValueTypeImpact
    1ResidentialResidential surcharge applies
    2CommercialNo residential surcharge
    This is valuable for accurate rate quoting — knowing the address type before rating prevents unexpected surcharges.

    Error Handling

    UPS APIs return structured error responses that you should handle gracefully:

    Common Error Codes

    Error CodeDescriptionResolution
    111100Invalid access tokenRefresh your OAuth token
    111210Rate limit exceededImplement exponential backoff
    120100Invalid addressValidate address before shipping
    120500Service not availableCheck service availability for route
    150000Package exceeds limitsCheck weight and dimension limits
    250000Shipper account invalidVerify account number and credentials

    Error Handling Best Practices

    PracticeImplementation
    Retry logicRetry transient errors (5xx, timeouts) with exponential backoff
    Circuit breakerStop calling API after repeated failures; fall back to cached rates
    LoggingLog all API requests and responses for debugging
    MonitoringAlert on error rate increases
    Graceful degradationShow cached rates or estimated delivery times when API is unavailable

    Rate Limiting and Performance

    UPS API Rate Limits

    EndpointLimitPeriod
    OAuth token~250 requestsPer day
    Rating API1,000 requestsPer minute
    Shipping API500 requestsPer minute
    Tracking API500 requestsPer minute
    Address Validation1,000 requestsPer minute

    Performance Optimization

    StrategyImplementationImpact
    Token cachingCache OAuth token; refresh 5 min before expiryEliminates 99%+ of token calls
    Rate cachingCache rate responses for same origin/dest/weight for 15–60 minReduces rating calls by 70%+
    Batch trackingTrack up to 35 packages in a single requestReduces tracking calls by 97%
    Connection poolingReuse HTTP connections30–50% latency reduction
    Async processingQueue label creation for non-real-time ordersSmooths API call volume

    Webhook Integration for Real-Time Tracking

    Instead of polling the Tracking API, UPS offers webhook notifications (Quantum View) that push tracking events to your server:

    Setting Up Webhooks

  • Contact your UPS account representative to enable Quantum View
  • Provide your webhook endpoint URL
  • Configure which events you want to receive
  • Implement the webhook receiver
  • Webhook Event Types

    EventDescription
    ManifestPackage label created
    Origin ScanPackage picked up by UPS
    In TransitPackage scanned at hub
    Out for DeliveryPackage on delivery vehicle
    DeliveredPackage delivered
    ExceptionDelivery exception occurred

    Webhook Receiver Implementation

    Your webhook endpoint should:

  • Accept POST requests with JSON payloads
  • Validate the webhook signature (provided in headers)
  • Return a 200 status within 10 seconds
  • Process the event asynchronously (do not block the response)
  • Handle duplicate events idempotently
  • Testing in Sandbox

    Sandbox Test Credentials

    UPS provides a sandbox (Customer Integration Environment, CIE) for testing:

    SettingValue
    Base URLhttps://wwwcie.ups.com
    Test account numbersProvided in developer portal
    Test addressesAny valid US address

    Testing Checklist

    Test CaseWhat to Verify
    Rate requestRates returned for all service levels
    Multi-package rateCorrect pricing for multi-piece shipments
    Label creationLabel image generated and valid
    Label voidSuccessful cancellation of created label
    Address validationValid, ambiguous, and invalid addresses handled
    TrackingStatus returned for test tracking numbers
    Error handlingApplication handles API errors gracefully
    Token refreshToken auto-refreshes before expiry
    Rate limitsApplication behaves correctly when throttled

    Test Tracking Numbers

    UPS provides test tracking numbers in the sandbox:

    Tracking NumberStatus
    1Z12345E0291980793Delivered
    1Z12345E0205271688In Transit
    1Z12345E6605272234Exception

    Production Deployment Checklist

    Before going live with your UPS API integration:

    ItemStatus
    OAuth token caching implementedRequired
    Error handling and retry logicRequired
    Rate limiting and throttlingRequired
    Logging and monitoringRequired
    Address validation before shippingRecommended
    Label storage and retrievalRequired
    Webhook receiver (Quantum View)Recommended
    DIM weight calculation verifiedRequired
    Surcharge handling (residential, fuel, etc.)Required
    Multi-package shipment supportIf applicable
    International shipment support (customs docs)If applicable
    Return label generationIf applicable
    Void/cancel shipment flowRequired
    Production credentials rotated from sandboxRequired

    Conclusion

    Integrating with the UPS API opens up powerful shipping capabilities for your application. The modern OAuth 2.0 REST APIs are well-documented, reliable, and performant. Start with the Rating and Address Validation APIs for customer-facing features, add the Shipping API for label generation, and implement webhook-based tracking for real-time visibility. Follow the best practices outlined in this guide — especially around token management, error handling, rate caching, and thorough testing — to build a robust, production-ready integration that scales with your business.

    Share this article:

    Ready to save on shipping?

    Get started with Atoship for free and access discounted USPS, UPS, and FedEx rates. No monthly fees, no contracts.

    Create Free Account