API Documentation

This is the documentation for the Packpin API v2. Here you will find the information needed to start using the Tracking API. This page contains the information about the setup and the correct usage of the API’s resources. This page does not contain any information about how you should setup your client interface used to make the requests to the API

API key

In order to use this API you will need to generate a Packpin API key in the Packpin Panel.

The base URL

https://api.packpin.com/v2

The requests

Your application (e.g. your e-shop) and the API communicates over HTTP. This means that the basic HTTP principles should be applied to your requests to the API.

All the transactions, the requests and the responses, should and will be encoded in JSON, therefore the Content-Type: application/json header must be set. You can omit the Accept header, because all the responses are returned in the JSON format anyway.

In order to verify and authenticate your application (e.g. your site), all of the requests that you make to the API must include your unique Packpin API Key header (Packpin-Api-Key), which you can generate and/or find in the Packpin Panel.

In short, each request:

  • must include the Packpin-Api-Key header. The value should be set to your unique Packpin API key, generated in the Packpin Panel.

  • must include the Content-Type: application/json header.

  • must be encoded in JSON.

Allowed HTTP methods

We use the RESTful architecture for this APIs resources. Here is a list of used HTTP methods in this API:

Method Description
GET Used to retrieve one or more resources. Successful request returns a JSON encoded response with the requested resource object(s). Typical response code is 200.
POST Used to create a new resource. Successful request returns a JSON encoded response with the updated resource object. Typical response code is 201.
PUT Used to update a resource. Successful request returns a JSON encoded response with the updated resource object. Typical response code is 200.
DELETE Used to delete a resource. Successful request returns an empty response. Typical response code is 204.

Typical Server Responses

We will respond with one of the following status codes.

Code Description
200 OK - The request was successful (some API calls may return 201 instead).
201 Created - The request was successful and a resource was created.
204 No Content - The request was successful but there is no representation to return (that is, the response is empty).
400 Bad Request - The request could not be understood or was missing required parameters.
401 Unauthorized - Authentication failed or user does not have permissions for the requested operation.
402 Payment Required - Payment required.
403 Forbidden - Access denied.
404 Not Found - Resource was not found.
405 Method Not Allowed - Requested method is not supported for the specified resource.
409 Conflict - The request could not be completed due to a conflict.
429 Too Many Requests - Exceeded API limits. Pause requests, wait one minute, and try again.
500 Server error
503 Service Unavailable - The service is temporary unavailable (e.g. scheduled Platform Maintenance). Try again later.

List of Tracking Statuses

String Description
delivered Item was delivered succesfully and this is last tracking status.
out_for_delivery Item is currently going to the last delivery location.
in_transit Item is shipped normally.
to_overseas Items is being shipped out of the country by local carrier/post office.
no_info Item has no tracking information yet or wrong carrier.
info_received Label have been created by sender, but item is not picked up by carrier.
in_transit Item is shipped normally.
pending We are colleclting information about this item.
failed_attempt Carrier for some reason failed to deliver item.

Request Rate Limiting

We do enforce a small amount of rate limiting. Please be aware that should you exceed these limits, you will receive a 429 error.

  • 30 requests every 10 seconds per IP

  • Maximum 20 simultaneous connections per IP

Resource parameters

These are the parameters used in URI’s of resources.

Parameter Description Example
‘carrier’ Carrier code. dhl
‘code’ Tracking code. 5076318866

Carriers 

This section describes the carrier related resources of the API.

URI Method Description
GET /carriers GET List all carriers
POST /carriers/detect POST Detect a carrier by tracking code

Carrier collection

List all carriers
/carriers

Returns list of all available carriers.

  • Request
  • Headers
    Content-Type: application/json
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": [
            {
                "code": "dhl",
                "name": "DHL",
                "phone": "+1 800 225 5345",
                "homepage": "http://www.dhl.com"
            },
            {
                "code": "dpd",
                "name": "DPD",
                "phone": "+49 01806 373 200",
                "homepage": "https://www.dpd.com"
            },
            {
                "code": "gls",
                "name": "GLS",
                "phone": "+44 247 621 3455",
                "homepage": "https://gls-group.eu"
            },
            {
                "code": "postnl3s",
                "name": "Post NL International 3S",
                "phone": "+31 0 900 0990",
                "homepage": "http://www.postnl.nl",
                "required_attributes":
                [
                    "track_postal_code",
                    "track_destination_country"
                ]
            },
            ...
        ]
    }
    

Carrier detection

Detect a carrier by tracking code
/carriers/detect

Returns a list of carriers that match the tracking code

Request body params:

Param Description
code The tracking code for which you are trying to find a carier. Required, string, E.x. RN123456789CN.
  • Request
  • Headers
    Content-Type: application/json
    Body
    {
        "code": "5076318866"
    }
    
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": [
            {
                "code": "dhl",
                "name": "DHL",
                "phone": "+1 800 225 5345",
                "homepage": "http://www.dhl.com"
            },
            {
                "code": "postau",
                "name": "Australian Post",
                "phone": "+61 3 8847 9980",
                "homepage": "http://auspost.com.au"
            },
            ...
        ]
    }
    

Trackings 

Manage your trackings

URI Method Description
GET /trackings GET List all trackings
POST /trackings POST Create a tracking item
POST /trackings/batch POST Add list of trackings
GET /trackings/{carrier}/{code} GET Retrieve a Tracking item
PUT /trackings/{carrier}/{code} PUT Update Tracking item
DELETE /trackings/{carrier}/{code} DELETE Remove a tracking code
POST /rtt POST Track an item in real time

Trackings Collection

List all trackings
/trackings
Param Description Default value
page (optional) Page to display 1
limit (optional) Items per page (max 1000) 100

E.x.

/trackings?page=1&limit=25
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": {
            "page": 1,
            "total": 500,
            "per_page": 100,
            "last_page": 5,
            "from": 1,
            "to": 100,
            "items": [
                {
            "id": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
            "code": "TEST164873",
            "carrier_code": "usps",
            "track_postal_code": null,
            "track_ship_date": null,
            "track_destination_country": null,
            "status": "pending",
            "original_address": "...",
            "original_state": "...",
            "original_zip": "...",
            "original_country": "...",
            "destination_address": "...",
            "destination_state": "...",
            "destination_zip": "...",
            "destination_country": "...",
            "created_at": "2015-01-21T14:47:47+02:00",
            "description": "Track description",
            "track_details": [
                                {
                            "carrier": "postlt",
                            "status": "delivered",
                            "status_string": "The item delivered and handed in to the addressee or another person based on authorization.",
                            "event_date": "2014-12-11",
                            "event_time": null,
                            "address": "Elektrėnai Post Office, Trakų Street 15, Elektrėnai",
                            "state": null,
                            "zip": null,
                            "country": "LT",
                        },
                        {
                            "carrier": "postlt",
                            "status": "out_for_delivery",
                            "status_string": "The item handed over to the courier/postman  or deposited with the post office for handing in  considering the type of the item.",
                            "event_date": "2014-12-11",
                            "event_time": null,
                            "address": "Elektrėnai Post Office, Trakų Street 15, Elektrėnai",
    
                            "country": "LT",
                        },
                        ...
                        {
                            "carrier": "postcn",
                            "status": "info_received",
                            "status_string": "Collection",
                            "event_date": "2014-11-19",
                            "event_time": "21:34:00",
                            "address": "浦江县电子商务分局",
                            "state": null,
                            "zip": null,
                            "country": "CN",
                        }
                    ]
                },
                ...
            ]
        }
    }
    

Trackings Collection

Create a tracking item
/trackings

Request body params:

Param Description
code Tracking code
carrier Carrier code
description (optional) Custom description
track_postal_code (optional) The postal code of receiver’s address. Required by some carriers.
track_ship_date (optional) Shipping date in YYYY-MM-DD format. Required by some carriers.
track_destination_country (optional) Destination Country of the shipment. Required by some carriers.
  • Request
  • Headers
    Content-Type: application/json
    Body
    {
        "code": "TEST0054",
        "carrier": "ups",
        "description": "Just an optional description for your tracking item"
    }
    
  • Response  201
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 201,
        "body": {
            "id": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
            "code": "TEST0054",
            "carrier_code": "ups",
            "track_postal_code": null,
            "track_ship_date": null,
            "track_destination_country": null,
            "status": "pending",
            "estimated_delivery": null,
            "original_address": "...",
            "original_state": "...",
            "original_zip": "...",
            "original_country": "...",
            "destination_address": "...",
            "destination_state": "...",
            "destination_zip": "...",
            "destination_country": "...",
            "created_at": "2015-01-21T14:47:47+02:00",
            "description": "Just an optional description for your tracking item",
            "track_details": []
        }
    }
    

Trackings batch insertion

Add list of trackings
/trackings/batch
  • Request
  • Headers
    Content-Type: application/json
    Body
    [
        {
            "code": "DNS783474224CN",
            "carrier": "postcn"
        },
        {
            "code": "DSS7873385",
            "carrier": "postgz"
        }
    ]
    
  • Response  201
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 201,
        "body": {
            "submitted": 2,
            "added": 2,
            "trackings": [
                {
                    "id": "1679091c5a880faf6fb5e6087eb1b2dc",
                    "code": "DNS783474224CN",
                    "carrier_code": "postcn",
                    "track_postal_code": null,
                    "track_ship_date": null,
                    "track_destination_country": null,
                    "status": "pending",
                    "estimated_delivery": null,
                    "original_address": "",
                    "original_state": "",
                    "original_zip": "",
                    "original_country": "",
                    "destination_address": "",
                    "destination_state": "",
                    "destination_zip": "",
                    "destination_country": "",
                    "created_at": "2015-02-01 14:47:47",
                    "description": ""
                },
                {
                    "id": "8f14e45fceea167a5a36dedd4bea2543",
                    "code": "DSS7873385",
                    "carrier_code": "postgz",
                    "track_postal_code": null,
                    "track_ship_date": null,
                    "track_destination_country": null,
                    "status": "pending",
                    "estimated_delivery": null,
                    "original_address": null,
                    "original_state": null,
                    "original_zip": null,
                    "original_country": null,
                    "destination_address": null,
                    "destination_state": null,
                    "destination_zip": null,
                    "destination_country": null,
                    "created_at": "2015-02-01 14:47:47",
                    "description": ""
                }
            ]
        }
    }
    
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": {
            "submitted": 2,
            "added": 1,
            "trackings": [
                {
                    "id": "1679091c5a880faf6fb5e6087eb1b2dc",
                    "code": "DNS783474224CN",
                    "carrier_code": "postcn",
                    "track_postal_code": null,
                    "track_ship_date": null,
                    "track_destination_country": null,
                    "status": "pending",
                    "estimated_delivery": null,
                    "original_address": "",
                    "original_state": "",
                    "original_zip": "",
                    "original_country": "",
                    "destination_address": "",
                    "destination_state": "",
                    "destination_zip": "",
                    "destination_country": "",
                    "created_at": "2015-02-01 14:47:47",
                    "description": ""
                }
            ],
            "error_code": "not_all_added",
            "error_description": "Some of the submitted tracking codes (if any) have not passed validation. The ones that passed will still be added to your tracking list",
            "errors": [
                {
                    "item": 0,
                    "error": "exists",
                    "description": "Code 'DSS7873385' with carrier 'postgz' is already added to your tracking list"
                }
            ]
        }
    }
    

Single tracking item

Retrieve a Tracking item
/trackings/{carrier}/{code}
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": {
            "id": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
            "code": "5076318866",
            "carrier_code": "dhl",
            "track_postal_code": null,
            "track_ship_date": null,
            "track_destination_country": null,
            "status": "delivered",
            "estimated_delivery": null,
            "original_address": "...",
            "original_state": "...",
            "original_zip": "...",
            "original_country": "...",
            "destination_address": "...",
            "destination_state": "...",
            "destination_zip": "...",
            "destination_country": "..."
            "created_at": "2015-01-21T14:47:47+02:00",
            "description": "test code",
            "track_details": [
    
                {
                    "carrier": "postlt",
                    "status": "delivered",
                    "status_string": "The item delivered and handed in to the addressee or another person based on authorization.",
                    "event_date": "2014-12-11",
                    "event_time": null,
                    "address": "Elektrėnai Post Office, Trakų Street 15, Elektrėnai",
                    "state": null,
                    "zip": null,
                    "country": "LT"
                },
                {
                    "carrier": "postlt",
                    "status": "out_for_delivery",
                    "status_string": "The item handed over to the courier/postman  or deposited with the post office for handing in  considering the type of the item.",
                    "event_date": "2014-12-11",
                    "event_time": null,
                    "address": "Elektrėnai Post Office, Trakų Street 15, Elektrėnai",
                    "state": null,
                    "zip": null,
                    "country": "LT"
                },
                ...
                {
                    "carrier": "postcn",
                    "status": "info_received",
                    "status_string": "Collection",
                    "event_date": "2014-11-19",
                    "event_time": "21:34:00",
                    "address": "浦江县电子商务分局",
                    "state": null,
                    "zip": null,
                    "country": "CN"
                }
            ]
        }
    }
    

Single tracking item

Update Tracking item
/trackings/{carrier}/{code}

Request body params:

Param Description Default value
description Item description "
  • Request
  • Headers
    Content-Type: application/json
    Body
    {
        "description": "New pair of socks" 
    }
    
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": {
            "id": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
            "code": "5076318866",
            "carrier_code": "dhl",
            "track_postal_code": null,
            "track_ship_date": null,
            "track_destination_country": null,
            "status": "delivered",
            "estimated_delivery": null,
            "original_address": "...",
            "original_state": "...",
            "original_zip": "...",
            "original_country": "...",
            "destination_address": "...",
            "destination_state": "...",
            "destination_zip": "...",
            "destination_country": "..."
            "created_at": "2015-01-21T14:47:47+02:00",
            "description": "New pair of socks",
            "track_details": []
        }
    }
    

Single tracking item

Remove a tracking code
/trackings/{carrier}/{code}
  • Response  204

Real time tracking

Track an item in real time
/rtt

Compared to normal tracking where status is refreshed once per hour, here we update information after request is made. Due to overload risks this feature requires custom activation. Contact support for more information.

Request body params:

Param Description
code Tracking code
carrier Carrier code
description (optional) Custom description
track_postal_code (optional) The postal code of receiver’s address. Required by some carriers.
track_ship_date (optional) Shipping date in YYYY-MM-DD format. Required by some carriers.
track_destination_country (optional) Destination Country of the shipment. Required by some carriers.
  • Request
  • Headers
    Content-Type: application/json
    Body
        {
            "code": "TEST0054",
            "carrier": "ups",
            "description": "Just an optional description for your real time tracking item"
        }
    
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
      "statusCode": 200,
      "body": {
        "id": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
        "code": "TEST0054",
        "carrier_code": "ups",
        "track_postal_code": null,
        "track_ship_date": null,
        "track_destination_country": null,
        "status": "delivered",
        "estimated_delivery": null,
        "original_address": "...",
        "original_state": "...",
        "original_zip": "...",
        "original_country": "...",
        "destination_address": "...",
        "destination_state": "...",
        "destination_zip": "...",
        "destination_country": "...",
        "created_at": "2015-07-27T11:51:44+03:00",
        "description": "Just an optional description for your real time tracking item",
        "track_details": [
          {
            "carrier": null,
            "status": "delivered",
            "status_string": "DELIVERED",
            "event_date": "2015-06-22",
            "event_time": "13:06:00",
            "address": "...",
            "state": null,
            "zip": null,
            "country": "..."
          }
        ]
      }
    

Notifications 

This section describes the notifications related resources of the API.

This section is different from rest of the API as not only we need to request the API, but the API makes requests to the backend of client application.

URI Method Description
POST /connectors POST Request email notifications
POST /webhook POST Webhook request

Request notifications

Request email notifications
/connectors

Request for emails to be sent via Packpin API. This method creates a webhook, that connect’s to your web app and gets the info needed when there’s a notification (status update) for a tracking code you added to the system. You should call this only once when you want to enable or disable the connector.

Request body params:

Param Description
plugin_type Must be set to custom
path Path to the webhook receiver (must be a valid URL) (overwritten every time request is sent)
secret Secret key to sign requests (preffered UUID, or atleast 10 symbols long) (overwritten every time request is sent)
enabled Send 1 or 0 to either enable or disable the webhook

Example PHP code to generate UUID:

<?php

function uuid(){
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}    
  • Request
  • Headers
    Content-Type: application/json
    Body
    {
        "plugin_type": "custom",
        "path": "http://yourdomain.tld/path/to/webhook",
        "secret": "ff34ae26-a854-4cab-b7c2-e201ead63ccf",
        "enabled": "1",
    }
    
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 200,
        "body": {
            "path": "http://packpin-connector.local/",
            "secret": "a26518ca-691f-482e-a9c6-0cf581fbe6da",
            "enabled": 1,
        }
    }
    
  • Response  400
  • Headers
    Content-Type: application/json
    Body
    {
        "status_code": 400,
        "body": {
            "reason": "Please enter a valid path!",
            "params": {}
        }
    }
    

Request email information

Webhook request
/webhook

This section describes how the webhook works. The request is made from Packpin API, and the response is what should the path return (defined in the /connectors request). You should check if the hash sent by the API is correct, to ensure that the data is coming from the right origin.

Example HMAC check in PHP:

<?php

// The secret you defined previously
$apiSecret = 'edba9703-2d7a-4e0e-94dc-c3879d5b3ad7';

// You should read the JSON POST from the API with Streams, not with POST super-global
$apiData = json_decode(file_get_contents('php://input'), true);

// This generates a simple HMAC, based on the data API sent
$hash = hash_hmac('sha256', json_encode($apiData['data']), $apiSecret);

if ($hash !== $apiData['hash']){
    // Headers should be set also
   echo json_encode(array("error" => "The hash is incorrect."));
   die;
}

// Go on with your code...
// $apiData['data'] holds all the needed info

You should proccess the data sent and just inform the user about a status change for his shipment. You should not call the Packpin API and fill the email with additional data for the shipment. You can add a link to a custom status page created by yourself (you can see an example in our CMS plugins), or a link we provided as track_link to let the user see more information about his shipment.

Response body params:

Param Description
sender_email The email of the
sender_name The name of the app
client_name The name of client
client_email The email of client
owner_email (optional) Email to send a copy of notification
owner_name (optional) Name of the owner
email_subject Email subject, must have order identification included
email_body Body of the email (HTML preffered)
  • Request  200
  • Headers
    Content-Type: application/json
    Body
    {
        "data": {
            "track": {
                "code": "058200005422993",
                "status": {
                    "slug": "in_transit",
                    "string": "In transit"
                },
                "deliver_date": "",
                "track_url": "https:\/\/packpin_com\/track\/dpd\/058200005422993\/"
            },
            "carrier": {
                "code": "dpd",
                "name": "DPD"
            }
        },
        "hash": "f46dfb4bd521c0fc36435229f9e1762793a9ae27ee8f9e71f1ac8e6746abc225"
    }
    
  • Response  200
  • Headers
    Content-Type: application/json
    Body
    {
        "sender_name": "My eshop",
        "sender_email": "my@shop.com",
        "client_name": "John Doe",
        "client_email": "john.doe@gmail.com",
        "owner_name": "John Owner",
        "owner_email": "john@shop.com",
        "email_subject": "Shipping notification for Order #104",
        "email_body": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<title>Packpin Notification<\/title>\n<\/head>\n<body>\nTracking code: <b>058200005422993<\/b> (Carrier: <b>DPD)<\/b><br\/>\nStatus: <b>In transit<\/b><br\/>\n<a href=\"https:\/\/packpin.com\/track\/dpd\/058200005422993\/\">More Info on Packpin.com<\/a>\n<\/body>\n<\/html>"
    }
    
  • Response  400
  • Headers
    Content-Type: application/json
    Body
    {
        "error" : "The hash is incorrect."
    }