{
  "info": {
    "name": "Topping Courier API",
    "description": "Book, price and follow Topping Courier deliveries from your own software.\n\n**Keys.** Business accounts create keys under My account, API. Send the key as `Authorization: Bearer tc_...`\n(or the `X-Api-Key` header). Test keys (`tc_test_...`) book sandbox orders that are never dispatched, charged or messaged;\nlive keys (`tc_live_...`) book real deliveries. Each account has daily and monthly call limits (429 when reached).\n\n**Boxes.** Several boxes to one address are one delivery: send `quantity` (boxes of one size) or `packages`\n(several sizes). It is priced at the largest box plus a small fee for each extra box.\n\n**Sizes.** Give each box the smallest size it fits. A box heavier than its size allows goes in the next size up.\n\n| size | What it is | Weight up to |\n|---|---|---|\n| `envelope` | Envelope: documents or a mini parcel | 1 lb |\n| `small` | Small: a shoebox or backpack | 10 lb |\n| `medium` | Medium: a moving box | 35 lb |\n| `large` | Large: a TV, a chair or big boxes | 50 lb |\n| `xl` | Extra large: furniture or an appliance | 100 lb |\n\nAlso accepted: doc, document or mini parcel for envelope; extra_large for xl.\n\n**Quotes.** A box over 100 lb, more than 30 boxes to one address, or a trip over 80 km has no instant price: don't\nbook a box over 100 lb through the API, and the other two are answered with 400 and `\"code\": \"quote_needed\"`.\nContact us and we'll price them.\n\n**Webhooks.** Add an HTTPS address under My account, API to get a signed POST for each event. Check the\n`Topping-Signature: t=<unix time>,v1=<hex>` header: v1 is the HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint\nsecret. Reply 2xx within 10 seconds; failed deliveries are retried with growing gaps.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://toppingcourier.ca"
    },
    {
      "key": "api_key",
      "value": "tc_test_paste_your_test_key"
    },
    {
      "key": "order_number",
      "value": "TC-100123"
    },
    {
      "key": "tracking",
      "value": "TC-100123-1"
    }
  ],
  "item": [
    {
      "name": "Prices",
      "item": [
        {
          "name": "Price a delivery (no key)",
          "request": {
            "method": "POST",
            "description": "A price for one delivery or a list of drops, without an account. The public price calculator. No API key and no account discounts.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/quotes",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "quotes"
              ]
            },
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"speed\": \"same_day\",\n  \"size_class\": \"small\",\n  \"distance_km\": 18,\n  \"deliveries\": 1,\n  \"boxes\": 4\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Quote an order",
          "request": {
            "method": "POST",
            "description": "The exact price and promise for an order, without booking it. Uses the account's own prices, discounts and rules, exactly as booking would.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders/quote",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders",
                "quote"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"speed\": \"same_day\",\n  \"pickup\": {\n    \"contact_name\": \"Front desk\",\n    \"company\": \"Maple Print Shop\",\n    \"phone\": \"647 555 0100\",\n    \"line1\": \"100 Queen St W\",\n    \"city\": \"Toronto\",\n    \"postal_code\": \"M5H 2N2\",\n    \"instructions\": \"Side door\"\n  },\n  \"drops\": [\n    {\n      \"contact_name\": \"Sam Lee\",\n      \"company\": \"Lee Dental\",\n      \"phone\": \"647 555 0133\",\n      \"email\": \"sam@example.com\",\n      \"line1\": \"1 Dundas St W\",\n      \"unit\": \"Suite 200\",\n      \"city\": \"Toronto\",\n      \"postal_code\": \"M5G 1Z3\",\n      \"size\": \"small\",\n      \"quantity\": 4,\n      \"distance_km\": 26,\n      \"reference\": \"PO-1002\"\n    },\n    {\n      \"contact_name\": \"Alex Kim\",\n      \"phone\": \"647 555 0144\",\n      \"line1\": \"200 Bay St\",\n      \"city\": \"Toronto\",\n      \"postal_code\": \"M5J 2J2\",\n      \"packages\": [\n        {\n          \"size\": \"small\",\n          \"quantity\": 3\n        },\n        {\n          \"size\": \"large\",\n          \"quantity\": 1\n        }\n      ],\n      \"distance_km\": 25\n    }\n  ],\n  \"contact\": {\n    \"name\": \"Ana Diaz\",\n    \"email\": \"ap@maple.example\",\n    \"phone\": \"647 555 0199\",\n    \"texts_ok\": false\n  },\n  \"payment_method\": \"invoice\",\n  \"reference\": \"Batch 42\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Orders",
      "item": [
        {
          "name": "Book an order",
          "request": {
            "method": "POST",
            "description": "Book one pickup with one or more drop-offs. Test keys book sandbox orders: never dispatched, charged or messaged.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"speed\": \"same_day\",\n  \"pickup\": {\n    \"contact_name\": \"Front desk\",\n    \"company\": \"Maple Print Shop\",\n    \"phone\": \"647 555 0100\",\n    \"line1\": \"100 Queen St W\",\n    \"city\": \"Toronto\",\n    \"postal_code\": \"M5H 2N2\",\n    \"instructions\": \"Side door\"\n  },\n  \"drops\": [\n    {\n      \"contact_name\": \"Sam Lee\",\n      \"company\": \"Lee Dental\",\n      \"phone\": \"647 555 0133\",\n      \"email\": \"sam@example.com\",\n      \"line1\": \"1 Dundas St W\",\n      \"unit\": \"Suite 200\",\n      \"city\": \"Toronto\",\n      \"postal_code\": \"M5G 1Z3\",\n      \"size\": \"small\",\n      \"quantity\": 4,\n      \"distance_km\": 26,\n      \"reference\": \"PO-1002\"\n    },\n    {\n      \"contact_name\": \"Alex Kim\",\n      \"phone\": \"647 555 0144\",\n      \"line1\": \"200 Bay St\",\n      \"city\": \"Toronto\",\n      \"postal_code\": \"M5J 2J2\",\n      \"packages\": [\n        {\n          \"size\": \"small\",\n          \"quantity\": 3\n        },\n        {\n          \"size\": \"large\",\n          \"quantity\": 1\n        }\n      ],\n      \"distance_km\": 25\n    }\n  ],\n  \"contact\": {\n    \"name\": \"Ana Diaz\",\n    \"email\": \"ap@maple.example\",\n    \"phone\": \"647 555 0199\",\n    \"texts_ok\": false\n  },\n  \"payment_method\": \"invoice\",\n  \"reference\": \"Batch 42\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List orders",
          "request": {
            "method": "GET",
            "description": "Your orders, newest first (25 a page). Filter with status, reference, created_after and created_before (YYYY-MM-DD). Page with page and page_size (up to 100).",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders"
              ]
            }
          }
        },
        {
          "name": "Get an order",
          "request": {
            "method": "GET",
            "description": "One order with its deliveries",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders/{{order_number}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders",
                "{{order_number}}"
              ]
            }
          }
        },
        {
          "name": "Cancel an order",
          "request": {
            "method": "POST",
            "description": "Cancel before pickup. After pickup it can't be cancelled through the API (409). Cancelling after a courier is assigned may cost a fee, as the Terms say.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders/{{order_number}}/cancel",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders",
                "{{order_number}}",
                "cancel"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Customer changed the order\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Print labels",
          "request": {
            "method": "GET",
            "description": "Shipping labels as PDF: one per box. Format from the setting api.label_format: 4 x 6 inch labels, or two on a letter page.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders/{{order_number}}/labels.pdf",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders",
                "{{order_number}}",
                "labels.pdf"
              ]
            }
          }
        },
        {
          "name": "Get a delivery",
          "request": {
            "method": "GET",
            "description": "One delivery by tracking number, with its proof of delivery",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/deliveries/{{tracking}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "deliveries",
                "{{tracking}}"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Testing",
      "item": [
        {
          "name": "Move a test order along",
          "request": {
            "method": "POST",
            "description": "Test orders only: assigned, picked_up, delivered or failed. Sends the same webhooks a real order would, so you can test your integration.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/orders/{{order_number}}/simulate",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "v1",
                "orders",
                "{{order_number}}",
                "simulate"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"to\": \"delivered\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    }
  ]
}