Docs / Quickstart

Ship your first invoice in five minutes

Create a key, POST a shipment, download the PDF. Everything else in the docs is a deeper look at the same round-trip.

1. Create an API key

Sign in, then visit /settings/api-keys, click Create new key, label it, and copy the raw key value — it looks like:

cik_a3d89ed455260775734e52cd4efd3ace7965a6a0bc12d4f8

We store only a SHA-256 hash of the key. If you lose it, revoke it and mint another.

2. Export the key to your shell

export CUSTOMS_INVOICE_API_KEY=cik_your_key_here

Or store it in your platform's secret manager (Vercel env vars, AWS Secrets Manager, GitHub Actions secrets, etc.).

3. Send a minimal invoice

The only required fields are the invoice header, shipper, consignee, and at least one line item.

curl

curl -X POST https://customs-invoice.com/api/v1/invoices \
  -H "Authorization: Bearer $CUSTOMS_INVOICE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "invoiceData": {
      "invoiceNumber": "INV-2026-001",
      "invoiceDate": "2026-04-24",
      "currency": "USD",
      "incoterms": "FOB",
      "transportMode": "sea",
      "shipper": { "name": "Acme Export", "address": "123 Trade St",
                   "city": "Shanghai", "zip": "200001", "country": "CN" },
      "consignee": { "name": "Global Buyer", "address": "Damstraat 5",
                     "city": "Amsterdam", "zip": "1012", "country": "NL" },
      "lineItems": [{
        "id": "1", "description": "Stainless steel bolts A2",
        "hsCode": "7318.15", "countryOfOrigin": "CN",
        "quantity": 10000, "unit": "PCS",
        "unitPrice": 0.05, "totalValue": 500.00
      }],
      "totalDeclaredValue": 500.00,
      "primaryDocument": "commercial",
      "additionalDocuments": []
    }
  }'

Node.js (fetch)

const res = await fetch(
  "https://customs-invoice.com/api/v1/invoices",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.CUSTOMS_INVOICE_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ invoiceData }),
  },
);
const { id, shortId, documents } = await res.json();
console.log(shortId, documents[0].signedUrl);

Python (requests)

import os, requests

r = requests.post(
    "https://customs-invoice.com/api/v1/invoices",
    headers={
        "Authorization": f"Bearer {os.environ['CUSTOMS_INVOICE_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={"invoiceData": invoice_data},
    timeout=120,
)
r.raise_for_status()
body = r.json()
print(body["shortId"], body["documents"][0]["signedUrl"])

4. Inspect the response

{
  "id": "e9d1a3b0-...-...",
  "shortId": "INV-2026-ABC123",
  "documents": [
    {
      "type": "commercial",
      "signedUrl": "https://.../invoices/e9d1.../commercial.pdf?token=...",
      "expiresIn": 3600
    }
  ]
}

Download each signedUrl and persist the PDF on your side — links expire in 1 hour.

5. Add packing list + CoO

Drop these into the same call to get multiple PDFs in one round-trip:

{
  "invoiceData": {
    ...
    "primaryDocument": "commercial",
    "additionalDocuments": ["packing-list", "certificate-of-origin"]
  }
}

The response's documents[] array will contain one entry per generated PDF.

You're done.

Everything else — proforma mode, certificate-of-origin fields, bulk upload — is documented in the API reference.

Open API reference