ParcelPanel API v2

Overview

ParcelPanel provides a RESTful API that allows you to programmatically access tracking information for your orders. This documentation covers the API endpoints, request parameters, response formats, and provides examples to help you integrate with ParcelPanel.

Base URL

All API requests should be made to the following base URL:

https://open.parcelpanel.com

Authentication

Authentication is required for all API requests. You need to include your API key in the request header.

x-parcelpanel-api-key: YOUR_API_KEY

Endpoints

Order Tracking

Retrieves tracking information for a specific order.

Endpoint: /api/v2/tracking/order

Method: GET

Request Parameters:

ParameterTypeRequiredDescription
order_numberstringNo*The order number (e.g., "#1034")
order_idstringNo*The order ID (e.g., "6126773010750")

*At least one of these parameters must be provided.

Response:

When successful, the API returns a JSON object with tracking details.

Success Response (200 OK):

{
  "order": {
    "order_id": 6140516335690,
    "order_number": "#1030",
    "order_tags": [
      "ParcelPanel",
      "API2.0"
    ],
    "store": {
      "name": "Example Store",
      "url": "https://example.myshopify.com"
    },
    "customer": {
      "name": "Aaliyah Bins",
      "email": "[email protected]",
      "phone": "12345678901"
    },
    "shipping_address": {
      "name": "Aaliyah Bins",
      "phone": null,
      "country": "United States",
      "country_code": "US",
      "province": "California",
      "province_code": "CA",
      "city": "Mountain View",
      "zip": "94043",
      "address1": "1600 Amphitheatre Parkway",
      "address2": null,
      "company": "Googleplex"
    },
    "tracking_link": "https://example.myshopify.com/apps/parcelpanel-test?order=1030&token=gro.elpmaxe_-_namllit.enelym",
    "shipments": [
      {
        "status": "DELIVERED",
        "status_label": "Delivered",
        "substatus": "Delivered_001",
        "substatus_label": "Delivered",
        "tracking_number": "YT2436021211003147",
        "carrier": {
          "name": "YunExpress",
          "code": "yunexpress",
          "contact": "400-8575-500",
          "logo_url": "https://cdn.parcelpanel.com/assets/common/images/express/yunexpress.png",
          "url": "http://www.yuntrack.com/track/detail?id=YT2436021211003147"
        },
        "transit_time": 11,
        "residence_time": 1,
        "estimated_delivery_date": {
          "source": "CUSTOM",
          "display_text": "Jan 12, 2025 - Jan 16, 2025"
        },
        "order_date": "2024-12-23T01:02:40+00:00",
        "fulfillment_date": "2024-12-24T01:25:40+00:00",
        "pickup_date": "2025-01-03T01:28:40",
        "delivery_date": "2025-01-13T14:36:00",
        "last_mile_tracking_supported": true,
        "last_mile": {
          "carrier_name": "USPS",
          "carrier_code": "usps",
          "tracking_number": "9261290358097849005373",
          "carrier_contact": "1 800-275-8777",
          "carrier_logo_url": "https://cdn.parcelpanel.com/assets/common/images/express/usps.png",
          "carrier_url": "https://tools.usps.com/go/TrackConfirmAction?qtc_tLabels1=9261290358097849005373"
        },
        "products": [
          {
            "id": 6941337714762,
            "title": "Amazing Aluminum Bag Collection10",
            "variant_id": 39969756151882,
            "variant_title": "xs / red / water",
            "quantity": 3,
            "image_url": "https://cdn.shopify.com/s/files/1/0563/3435/2458/products/AAUvwnj0ICORVuxs41ODOvnhvedArLiSV20df7r8XBjEUQ_s900-c-k-c0x00ffffff-no-rj_147ad8db-b4f4-40a5-b751-c0a8428b8ae7-951612.jpg?v=1678447639",
            "url": "https://example.myshopify.com/apps/parcelpanel/bland?q=eyJ0IjoxNzQ1NTY1MzAzLCJwcm9kdWN0X2lkIjo2OTQxMzM3NzE0NzYyLCJoYW5kbGUiOiJhbWF6aW5nLWFsdW1pbnVtLWJhZy1jb2xsZWN0aW9uMTAiLCJmcm9tIjoicGFyY2VscGFuZWwtYWRtaW4ifQ"
          }
        ],
        "checkpoints": [
          {
            "detail": "Delivered, In/At Mailbox, FAIRBANKS, AK 99701",
            "status": "DELIVERED",
            "status_label": "Delivered",
            "substatus": "Delivered_001",
            "substatus_label": "Delivered",
            "checkpoint_time": "2025-01-13T14:36:00"
          },
          {
            "detail": "Out for Delivery, FAIRBANKS, AK 99701",
            "status": "OUT_FOR_DELIVERY",
            "status_label": "Out for delivery",
            "substatus": "OutForDelivery_001",
            "substatus_label": "Out for delivery",
            "checkpoint_time": "2025-01-13T06:45:00"
          }
        ]
      }
    ]
  }
}

Error Response (404 Not Found):

{
  "errors": "Order not found"
}

Response Object Definitions

Order Object

FieldTypeNullableDescription
order_idintegerNoUnique identifier for the order
order_numberstringNoThe order number displayed to customers
order_tagsarrayNoArray of tags associated with the order
storeobjectNoInformation about the store
customerobjectNoInformation about the customer
shipping_addressobjectYesShipping address information
tracking_linkstringNoLink to track the order
shipmentsarrayNoArray of shipment objects

Store Object

FieldTypeNullableDescription
namestringNoStore name
urlstringNoStore URL

Customer Object

FieldTypeNullableDescription
namestringYesCustomer name
emailstringYesCustomer email address
phonestringYesCustomer phone number

Shipping Address Object

FieldTypeNullableDescription
namestringYesRecipient name
phonestringYesRecipient phone number
countrystringYesCountry name
country_codestringYesCountry code (ISO format)
provincestringYesProvince or state name
province_codestringYesProvince or state code
citystringYesCity name
zipstringYesZIP or postal code
address1stringYesAddress line 1
address2stringYesAddress line 2
companystringYesCompany name

Shipment Object

FieldTypeNullableDescription
statusstringNoMain status code (PENDING, INFO_RECEIVED, IN_TRANSIT, OUT_FOR_DELIVERY, READY_FOR_PICKUP, DELIVERED, EXCEPTION, FAILED_ATTEMPT, EXPIRED)
status_labelstringNoHuman-readable main status
substatusstringNoDetailed status code
substatus_labelstringNoHuman-readable detailed status
tracking_numberstringNoTracking number for the shipment
carrierobjectYesInformation about the carrier
transit_timeintegerNoTransit time in days
residence_timeintegerYesResidence time in days
estimated_delivery_dateobjectYesEstimated delivery date information
order_datestringNoDate when the order was placed (ISO 8601 format)
fulfillment_datestringYesDate when the order was fulfilled (ISO 8601 format)
pickup_datestringYesDate when the package was picked up (ISO 8601 format)
delivery_datestringYesDate when the package was delivered (ISO 8601 format)
last_mile_tracking_supportedbooleanNoWhether last mile tracking is supported
last_mileobjectYesInformation about the last mile carrier
productsarrayNoProducts included in the shipment
checkpointsarrayNoArray of checkpoint objects showing the package's journey

Carrier Object

FieldTypeNullableDescription
namestringNoCarrier name
codestringNoCarrier code (see carrier list)
urlstringNoTracking URL for the carrier
logo_urlstringNoURL to the carrier's logo
contactstringNoContact information for the carrier

Last Mile Carrier Object

FieldTypeNullableDescription
carrier_namestringNoLast mile carrier name
carrier_codestringNoLast mile carrier code
tracking_numberstringNoLast mile tracking number
carrier_contactstringYesContact information for the last mile carrier
carrier_logo_urlstringYesURL to the last mile carrier's logo
carrier_urlstringYesTracking URL for the last mile carrier

Product Object

FieldTypeNullableDescription
idintegerYesProduct ID
titlestringNoProduct title
variant_idintegerYesVariant ID
variant_titlestringYesVariant title
quantityintegerNoQuantity of the product
image_urlstringYesURL to the product image
urlstringYesURL to the product page

Checkpoint Object

FieldTypeNullableDescription
detailstringNoDetailed description of the checkpoint
statusstringYesStatus code at this checkpoint
status_labelstringYesHuman-readable status
substatusstringYesDetailed status code
substatus_labelstringYesHuman-readable detailed status
checkpoint_timestringNoTime of the checkpoint (ISO 8601 format)

Estimated Delivery Date Object

FieldTypeNullableDescription
sourcestringNoSource of the estimated delivery date (SHOPIFY, CARRIER, CUSTOM)
display_textstringNoHuman-readable display text for the estimated delivery date

Enumeration Values

Main Status Codes

The status field in shipments and checkpoints can have the following values:

CodeDescription
PENDINGShipment is pending, not yet processed
INFO_RECEIVEDShipping information has been received
IN_TRANSITPackage is in transit
OUT_FOR_DELIVERYPackage is out for delivery
READY_FOR_PICKUPPackage is ready for pickup
DELIVEREDPackage has been delivered
EXCEPTIONAn issue has occurred with the shipment
FAILED_ATTEMPTDelivery attempt failed
EXPIREDTracking has expired

Sub Status Codes

The substatus field provides more detailed information about the shipment status:

CodeMain StatusDescription
Pending_001PENDINGPending
Pending_002PENDINGOrder processed
InfoReceived_001INFO_RECEIVEDShipping information received
InTransit_001IN_TRANSITIn transit
InTransit_002IN_TRANSITDeparted from facility
InTransit_003IN_TRANSITArrived at facility
InTransit_004IN_TRANSITCustoms clearance completed
InTransit_005IN_TRANSITCustoms clearance delay
InTransit_006IN_TRANSITIn transit to next facility
InTransit_007IN_TRANSITInternational shipment release
OutForDelivery_001OUT_FOR_DELIVERYOut for delivery
OutForDelivery_002OUT_FOR_DELIVERYOut for delivery again
ReadyForPickup_001READY_FOR_PICKUPReady for pickup
Delivered_001DELIVEREDDelivered
Delivered_002DELIVEREDDelivered to agent
Delivered_003DELIVEREDDelivered to neighbor
Delivered_004DELIVEREDDelivered to pickup point
Exception_001EXCEPTIONUnknown exception
Exception_002EXCEPTIONDelivery exception
Exception_003EXCEPTIONReturned to sender
Exception_004EXCEPTIONAddress issue
Exception_005EXCEPTIONDamaged
Exception_006EXCEPTIONLost
Exception_007EXCEPTIONHeld at customs
Exception_008EXCEPTIONDelivery rescheduled
FailedAttempt_001FAILED_ATTEMPTFailed attempt
FailedAttempt_002FAILED_ATTEMPTRecipient not available
FailedAttempt_003FAILED_ATTEMPTOffice closed
FailedAttempt_004FAILED_ATTEMPTWeather delay
Expired_001EXPIREDTracking expired

Estimated Delivery Date Source

The source field in the estimated_delivery_date object can have the following values:

CodeDescription
SHOPIFYEstimated delivery date from Shopify
CARRIEREstimated delivery date from the carrier
CUSTOMCustom estimated delivery date

Code Examples

cURL

curl -X GET "https://open.parcelpanel.com/api/v2/tracking/order?order_number=1030" \
  -H "x-parcelpanel-api-key: YOUR_API_KEY"

Python

import requests

url = "https://open.parcelpanel.com/api/v2/tracking/order"
headers = {
    "x-parcelpanel-api-key": "YOUR_API_KEY"
}
params = {
    "order_number": "1030"
}

response = requests.get(url, headers=headers, params=params)
print(response.json())

Node.js

const axios = require('axios');

const options = {
  method: 'GET',
  url: 'https://open.parcelpanel.com/api/v2/tracking/order',
  params: {
    order_number: '1030'
  },
  headers: {
    'x-parcelpanel-api-key': 'YOUR_API_KEY'
  }
};

axios.request(options)
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.error(error);
  });

PHP

<?php
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://open.parcelpanel.com/api/v2/tracking/order?order_number=1030",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "x-parcelpanel-api-key: YOUR_API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
?>

Go

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	// Create a new request
	req, err := http.NewRequest("GET", "https://open.parcelpanel.com/api/v2/tracking/order", nil)
	if err != nil {
		fmt.Println("Error creating request:", err)
		return
	}

	// Add query parameters
	q := req.URL.Query()
	q.Add("order_number", "1030")
	req.URL.RawQuery = q.Encode()

	// Add headers
	req.Header.Add("x-parcelpanel-api-key", "YOUR_API_KEY")

	// Send the request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request:", err)
		return
	}
	defer resp.Body.Close()

	// Read the response body
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	// Print the response
	fmt.Println(string(body))
}

Java

import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ParcelPanelApiExample {
    public static void main(String[] args) {
        try {
            // Create URL with query parameters
            URL url = new URL("https://open.parcelpanel.com/api/v2/tracking/order?order_number=1030");
            
            // Open connection
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            // Set request method
            connection.setRequestMethod("GET");
            
            // Set headers
            connection.setRequestProperty("x-parcelpanel-api-key", "YOUR_API_KEY");
            
            // Get response code
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            
            // Read response
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();
            
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            
            // Print response
            System.out.println(response.toString());
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

C#

using System;
using System.Net.Http;
using System.Threading.Tasks;

class ParcelPanelApiExample
{
    static async Task Main()
    {
        // Create HttpClient
        using (HttpClient client = new HttpClient())
        {
            // Set base address
            client.BaseAddress = new Uri("https://open.parcelpanel.com");
            
            // Add headers
            client.DefaultRequestHeaders.Add("x-parcelpanel-api-key", "YOUR_API_KEY");
            
            try
            {
                // Send request
                HttpResponseMessage response = await client.GetAsync("/api/v2/tracking/order?order_number=1030");
                
                // Ensure successful response
                response.EnsureSuccessStatusCode();
                
                // Read response content
                string responseContent = await response.Content.ReadAsStringAsync();
                
                // Output response
                Console.WriteLine(responseContent);
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Error: {e.Message}");
            }
        }
    }
}

Ruby

require 'net/http'
require 'uri'
require 'json'

# Set the URL
uri = URI.parse('https://open.parcelpanel.com/api/v2/tracking/order')

# Add query parameters
params = { order_number: '1030' }
uri.query = URI.encode_www_form(params)

# Create HTTP request
request = Net::HTTP::Get.new(uri)

# Add headers
request['x-parcelpanel-api-key'] = 'YOUR_API_KEY'

# Create HTTP connection
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

begin
  # Send the request
  response = http.request(request)
  
  # Check if response was successful
  if response.code == '200'
    # Parse and print the JSON response
    result = JSON.parse(response.body)
    puts result
  else
    puts "Error: #{response.code} - #{response.message}"
  end
rescue => e
  puts "Exception: #{e.message}"
end

Rate Limits

The API enforces rate limits to ensure service stability and fair usage across all users. The current rate limit is:

  • 4 requests per second per API key

If you exceed the rate limit, the API will return a 429 Too Many Requests status code. In this case, you should implement an exponential backoff strategy in your application.

Need higher limits? If your application requires a higher rate limit, please contact ParcelPanel Support at [email protected] to discuss your specific needs.

Error Codes

Status CodeDescription
400Bad Request - Your request is invalid
401Unauthorized - Your API key is wrong
404Not Found - The requested resource could not be found
422Unprocessable Entity - The parameters were valid but the request failed due to semantic errors
429Too Many Requests - You have exceeded the rate limit
500Internal Server Error - We had a problem with our server

Support

For any questions or issues regarding the API, please contact our support team at [email protected].