What is it?
SOM API: Booking with Customs Declarations defines how to include customs declaration data in cross-border shipments booked via the Ingrid SOM API. It covers three supported integration paths depending on how your fulfillment systems are structured, plus a complete field reference for GeneralCustomsDeclaration and GeneralCustomsDeclarationItem.
Any shipment that crosses a customs border requires a customs_declaration object in the booking call. Ingrid does not derive customs data automatically — it must come from your systems.
Which path to use
Your setup | Recommended path |
You use Ingrid Delivery Checkout and have a | Path 1: TOS ID + inline customs declaration |
You provide all shipment data directly (no Delivery Checkout) | Path 2: Full API booking + inline customs declaration |
Customs data comes from a separate system or pipeline step | Path 3: Create shipment → upsert customs → book |
Path 1: TOS ID booking + inline customs declaration
Use when you book shipments using a tos_id from a completed Ingrid Delivery Checkout session. Ingrid resolves addresses, shipping method, and line items from the checkout session — but customs data must still be included in every booking call.
POST /v1/som/shipments.createAndBook
{
"tos_id": "{{tos_id}}",
"customs_declaration": {
"general_customs_declaration": {
"contents_type": "SALE_OF_GOODS",
"contents_explanation": "Clothing",
"invoice_number": "INV-2024-001",
"invoice_date": "2024-01-15",
"incoterms": "DDP",
"currency": "SEK",
"seller_identification_numbers": {
"vat_number": "SE123456789001",
"eori_number": "SE123456789"
},
"items": [
{
"description": "Cotton T-shirt",
"hs_tariff_number": "6109100010",
"country_of_origin": "CN",
"quantity": 2,
"unit_value": 29900,
"unit_net_weight": 200,
"unit_gross_weight": 250
}
]
}
}
}
Path 2: Full API booking + inline customs declaration
Use when you provide the full shipment payload directly — no Delivery Checkout involved. The customs_declaration block is identical to Path 1.
POST /v1/som/shipments.createAndBook
{
"shipment": {
"address_from": { ... },
"address_to": { ... },
"parcels": [ ... ]
},
"customs_declaration": {
"general_customs_declaration": {
"contents_type": "SALE_OF_GOODS",
"contents_explanation": "Clothing",
"incoterms": "DDP",
"currency": "SEK",
"seller_identification_numbers": {
"vat_number": "SE123456789001",
"eori_number": "SE123456789"
},
"items": [
{
"description": "Cotton T-shirt",
"hs_tariff_number": "6109100010",
"country_of_origin": "CN",
"quantity": 2,
"unit_value": 29900,
"unit_net_weight": 200,
"unit_gross_weight": 250
}
]
}
}
}
Path 3: Create shipment → upsert customs declaration → book
Use when customs data is produced by a separate system or pipeline step after shipment creation.
Step 1: Create the shipment
POST /v1/som/shipments.create
{
"shipment": {
"address_from": { ... },
"address_to": { ... },
"parcels": [ ... ]
}
}Response includes the shipment_id needed for the next steps.
Step 2: Upsert the customs declaration
POST /v1/som/shipments.upsertCustomsDeclaration
{
"shipment_id": "{{shipment_id}}",
"general_customs_declaration": {
"contents_type": "SALE_OF_GOODS",
"contents_explanation": "Clothing",
"incoterms": "DDP",
"currency": "SEK",
"seller_identification_numbers": {
"vat_number": "SE123456789001",
"eori_number": "SE123456789"
},
"items": [
{
"description": "Cotton T-shirt",
"hs_tariff_number": "6109100010",
"country_of_origin": "CN",
"quantity": 2,
"unit_value": 29900,
"unit_net_weight": 200,
"unit_gross_weight": 250
}
]
}
}Calling upsertCustomsDeclaration again on the same shipment will replace the existing customs declaration.
Step 3: Book the shipment
POST /v1/som/shipments.bookParcels
{
"shipment_id": "{{shipment_id}}"
}Ensure Step 2 completes successfully before calling bookParcels.
Reducing payload with booking rules
Many customs declaration fields are the same for every order on a given route — seller tax IDs, incoterms, currency, importer address. With booking rules, Ingrid can populate these static fields automatically at booking time based on conditions like origin country.
What booking rules can auto-populate:
seller_identification_numbers— VAT, EORI per origin countryincotermsandplace_of_incotermscurrencysold_to— importer or customs broker address. Note: Theregionfield (state/province) is required for: United States, Canada, Australia, China, Brazil, Mexico, Malaysia, New Zealand.Carrier-specific metadata
What you must always send per order:
items[]— HS tariff number, country of origin, value, net and gross weight per line itemcontents_typeandcontents_explanation(unless configured as a static rule)invoice_numberandinvoice_date(if required by your carrier)
Booking rules are configured by the Ingrid team. Contact your integration manager or ask Iris, Ingrid's AI assistant, in the chat on the Ingrid Help Center, and share your route setup and which fields are static per origin country or warehouse. Iris can hand your request over to the Ingrid team or create a ticket for you. If you can't reach Iris, email [email protected].
Field reference
GeneralCustomsDeclaration
Field | Type | Required | Description |
| string | Yes | ISO 4217 currency code (e.g. SEK, EUR, USD) |
| enum | Yes | SALE_OF_GOODS, GIFT, RETURN, COMMERCIAL_SAMPLE, DOCUMENTS, OTHER, DANGEROUS_GOODS, HUMANITARIAN_DONATIONS |
| string | Yes | Short description of contents (e.g. "Clothing") |
| enum | Carrier-dependent | DDP, DAP, DDU, EXW, FCA, etc. |
| string | Carrier-dependent | Unique invoice identifier |
| string | Carrier-dependent | RFC-3339 date when invoice was issued |
| integer | Carrier-dependent | Total parcel weight in grams including packaging |
| Address | Carrier-dependent | Exporter address |
| TaxIdentificationNumbers | Carrier-dependent | Seller EORI, VAT, VOEC, IOSS, etc. |
| Address | Carrier-dependent | Buyer/importer address. |
| TaxIdentificationNumbers | Carrier-dependent | Buyer EORI, VOEC, PCCC, etc. |
| Payer | No | Who pays import duties. Defaults to sender |
| string | Carrier-dependent | Legal statement for customs processing |
| GeneralCustomsDeclarationItem[] | Yes | Line items in the declaration |
GeneralCustomsDeclarationItem
Field | Type | Required | Description |
| string | Yes | Item name |
| string | Yes | Product SKU |
| string | Recommended | Composition or material |
| string | Yes | Harmonized System tariff code (6–10 digits) |
| string | Yes | ISO Alpha-2 country code where item was manufactured |
| integer | Yes | Number of units |
| integer (uint32) | Yes | Value per single unit in smallest currency unit (cents/öre). E.g., €128.25 = |
| integer | Yes | Net weight per unit in grams |
| integer | Recommended | Gross weight per unit in grams |
| string | No | Item brand |
| string | No | Commodity category |
FAQ
Do I need to send
customs_declarationif I book with a TOS ID?
Yes. A TOS ID reduces the shipment data you need to send, but cross-border shipments still requirecustoms_declarationin every booking call.What is the difference between Path 1 and Path 2?
Thecustoms_declarationblock is identical in both. The only difference is whether shipment data is resolved from a TOS order (Path 1) or provided directly in the request (Path 2).Does
upsertCustomsDeclarationoverwrite existing customs data?
Yes — it is an upsert. Calling it again on the same shipment replaces the existing customs declaration.Can I update the customs declaration after booking?
No. OncebookParcelshas been called, the customs declaration cannot be changed. If corrections are needed, contact your carrier directly.Can booking rules fully replace my customs data?
No. Booking rules auto-fill static per-route fields, but item-level data (HS codes, values, weights, country of origin) must always come from your systems per order.I'm getting a validation error on
unit_value— what format should I use?
unit_valueis auint32field and must be an integer in the smallest currency unit (cents, öre, pence). For example, €128.25 should be sent as12825. Sending a decimal value like128.25will be rejected with aninvalid value for uint32 field unitValueerror.Who do I contact to set up booking rules?
Contact your Ingrid integration manager or ask Iris, Ingrid's AI assistant, in the chat on the Ingrid Help Center, and share your route setup and which fields are static per origin country, destination, or carrier product. Iris can hand your request over to the Ingrid team or create a ticket for you. If you can't reach Iris, email [email protected].
Related documentation
Migration guide: General Customs Declaration — migrating from deprecated declaration types (
cn22,cn23,cp72, etc.) toGeneralCustomsDeclarationMigration guide: Customs Tax ID — migrating from string-based tax ID fields to structured
TaxIdentificationNumbersobjects
