AppID and RestApiKeyAppID and RestApiKey for a short-lived token, then include that token in the Authorization header of every subsequent request.POST https://partnerapi.flavorcloud.com/Auth{
"AppID": "{{APP_ID}}",
"RestApiKey": "{{REST_API_KEY}}"
}{
"Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"RootRequestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Token value — you will use it for all subsequent API calls.| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | The Token value returned by POST /Auth |
Token expiry: If you receive a 401 Authentication Error, your token has expired. CallPOST /Authagain to obtain a new one.
Keep your credentials secure. Do not expose your AppIDorRestApiKeyin client-side code or public repositories.
0. Authenticate → POST /Auth (exchange credentials for JWT token)
1. Get rates → POST /Rates (returns HashKey + DutyHashKey)
2. Create shipment → POST /Shipments (returns ShipmentID + LabelUrl)
3. Receive tracking → Webhook push (real-time status updates)
4. Look up tracking → GET /Tracking/... (on-demand status for a specific shipment)HashKey and DutyHashKey returned by /Rates should be passed to /Shipments to lock in the rated price and avoid recalculating duties. Store the ShipmentID returned by /Shipments — you will need it for creating returns.POST https://partnerapi.flavorcloud.com/RatesHashKey and DutyHashKey values that you pass to /Shipments to lock in the rated price and avoid recalculating duties and taxes.Weight rule: If the sum of all Pieces[].Weightvalues exceedsPackage.Weight, the higher total is used for rating. SetPackage.Weightto at least the sum of piece weights to avoid discrepancies.
Headers required: Content-Type: application/jsonandAuthorization: <your JWT token>
{
"Reference": "ORDER-56789",
"WeightUnit": "LB",
"DimensionUnit": "IN",
"Currency": "USD",
"Insurance": "N",
"ReasonForExport": "merchandise",
"ShipFromAddress": {
"Name": "Acme Apparel",
"AttentionName": "Shipping Department",
"AddressLine1": "200 Townsend Street",
"City": "San Francisco",
"State": "CA",
"Country": "US",
"Zip": "94107",
"Phone": "4155550100",
"Email": "shipping@acmeapparel.com"
},
"ShipToAddress": {
"Name": "Jane Smith",
"AttentionName": "Jane Smith",
"AddressLine1": "89 Pall Mall",
"AddressLine2": "St. James's",
"City": "London",
"State": "",
"Country": "GB",
"Zip": "SW1Y 5HS",
"Phone": "442071234567",
"Email": "jane.smith@example.com"
},
"Pieces": [
{
"Quantity": 1,
"Weight": 0.4,
"SalePrice": 290.00,
"HSCode": "610910",
"OriginCountryCode": "US",
"Description": "Blue Polyester T-Shirt"
}
],
"Package": {
"Weight": 1.25
}
}| Field | Type | Required | Description |
|---|---|---|---|
Reference | string | Yes | Your order or reference number |
WeightUnit | string | Yes | LB or KG |
DimensionUnit | string | Yes | IN or CM |
Currency | string | Yes | 3-letter ISO currency code (e.g., USD) |
Insurance | string | No | Y to request insurance, N to decline. Defaults to N |
ReasonForExport | string | Yes | See valid values |
ShipFromAddress | object | Yes | Sender address (see Address Fields) |
ShipToAddress | object | Yes | Recipient address (see Address Fields) |
Pieces | array | Yes | Line items in the shipment |
Pieces[].Quantity | integer | Yes | Number of units |
Pieces[].Weight | number | Yes | Weight of this item (in WeightUnit) |
Pieces[].SalePrice | number | Yes | Declared value per unit (in Currency) |
Pieces[].HSCode | string | Yes | 6-digit HS code |
Pieces[].OriginCountryCode | string | Yes | 2-letter ISO country of manufacture |
Pieces[].Description | string | Yes | Plain-language item description |
Package | object | Yes | Overall package dimensions and weight |
Package.Weight | number | Yes | Total package weight including packaging |
Package.Length | number | No | Package length (in DimensionUnit) |
Package.Width | number | No | Package width |
Package.Height | number | No | Package height |
{
"RateId": 7165631,
"Reference": "ORDER-56789",
"Currency": "USD",
"Express": {
"DDP": {
"HashKey": "Z15DTMI",
"ShippingCost": 29.18,
"ActualShippingCost": 29.18,
"DiscountedShippingCost": 29.18,
"Insurance": 0,
"Days": "2-3 business days",
"Carrier": "FlavorCloud",
"LandedCostDetail": {
"AIT": 0,
"Duty": 7,
"SalesTax": 66,
"LandedCost": 73,
"DutyHashKey": "Z1Afo2b",
"ActualAIT": 0,
"ActualDuty": 7,
"ActualSalesTax": 66,
"ActualLandedCost": 73
}
},
"DDU": {
"HashKey": "Z2rHnBP",
"ShippingCost": 23.18,
"ActualShippingCost": 23.18,
"DiscountedShippingCost": 23.18,
"Insurance": 0,
"Days": "2-3 business days",
"Carrier": "FlavorCloud"
}
},
"Standard": {
"DDP": {
"HashKey": "Z3kQmNR",
"ShippingCost": 14.50,
"ActualShippingCost": 14.50,
"DiscountedShippingCost": 14.50,
"Insurance": 0,
"Days": "8-12 business days",
"Carrier": "FlavorCloud",
"LandedCostDetail": {
"AIT": 0,
"Duty": 7,
"SalesTax": 66,
"LandedCost": 73,
"DutyHashKey": "Z1Bgo3c"
}
},
"DDU": {
"HashKey": "Z4pRnAS",
"ShippingCost": 10.50,
"ActualShippingCost": 10.50,
"DiscountedShippingCost": 10.50,
"Insurance": 0,
"Days": "8-12 business days",
"Carrier": "FlavorCloud"
}
},
"RootRequestId": "b0f9e4f2-53c9-4d8f-8376-dba956367e40"
}Express and Standard service level objects when rates are available for both. If only one service level is available, only that object will be present. Check for the existence of each before displaying rates.HashKey. Pass the chosen HashKey (and DutyHashKey for DDP rates) to /Shipments.Duty and SalesTax may be 0 when the shipment value falls below the destination country's de minimis threshold — the minimum declared value at which import duties and taxes apply. This is expected and not an error.ShippingCost reflects any applicable account discounts. ActualShippingCost is the undiscounted carrier cost.POST https://partnerapi.flavorcloud.com/ShipmentsHashKey and DutyHashKey from your /Rates response to lock in the rated price.No address validation: FlavorCloud does not validate destination addresses. Invalid addresses will not be rejected but may result in failed deliveries or additional carrier fees. We recommend validating addresses with a third-party service before submitting.
Multiple packages: You can include multiple shipment objects in one call if the ShipFromAddressandShipToAddressare the same. Each will receive its own label.
Store ShipmentID: The ShipmentIDreturned in the response is required for manifesting and for creating return shipments. Store it against your order record.
Headers required: Content-Type: application/jsonandAuthorization: <your JWT token>
{
"Reference": "ORDER-56789",
"ServiceCode": "EXPRESS",
"TermsOfTrade": "DDP",
"WeightUnit": "LB",
"DimensionUnit": "IN",
"Currency": "USD",
"ReasonForExport": "merchandise",
"PickUpDate": "2025-04-15",
"HashKey": "Z15DTMI",
"DutyHashKey": "Z1Afo2b",
"ShipFromAddress": {
"Name": "Acme Apparel",
"AttentionName": "Shipping Department",
"AddressLine1": "200 Townsend Street",
"City": "San Francisco",
"State": "CA",
"Country": "US",
"Zip": "94107",
"Phone": "4155550100",
"Email": "shipping@acmeapparel.com"
},
"ShipToAddress": {
"Name": "Jane Smith",
"AttentionName": "Jane Smith",
"AddressLine1": "89 Pall Mall",
"AddressLine2": "St. James's",
"City": "London",
"State": "",
"Country": "GB",
"Zip": "SW1Y 5HS",
"Phone": "442071234567",
"Email": "jane.smith@example.com"
},
"Shipments": [
{
"Piece": [
{
"Quantity": 1,
"Weight": 0.4,
"SalePrice": 290.00,
"HSCode": "610910",
"OriginCountryCode": "US",
"Description": "Blue Polyester T-Shirt"
}
],
"Package": {
"Reference": "ORDER-56789",
"Weight": 1.25,
"Length": 12,
"Width": 8,
"Height": 3
}
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
Reference | string | Yes | Your order number. Must be unique per shipment |
ServiceCode | string | Yes | STANDARD or EXPRESS |
TermsOfTrade | string | Yes | DDP (Delivered Duty Paid) or DDU (Delivered Duty Unpaid) |
WeightUnit | string | Yes | LB or KG |
DimensionUnit | string | Yes | IN or CM |
Currency | string | Yes | 3-letter ISO currency code |
ReasonForExport | string | Yes | See valid values |
PickUpDate | string | No | Requested pickup date in YYYY-MM-DD format |
HashKey | string | Recommended | From /Rates response. Locks in the rated price |
DutyHashKey | string | Recommended | From /Rates DDP response. Locks in duty calculation |
ShipFromAddress | object | Yes | Sender address |
ShipToAddress | object | Yes | Recipient address |
Shipments | array | Yes | One or more packages |
Shipments[].Piece | array | Yes | Line items for this package |
Shipments[].Package | object | Yes | Physical package details |
Shipments[].Package.Reference | string | No | Package-level reference (e.g., package number) |
Shipments[].Package.Weight | number | Yes | Package weight |
Shipments[].Package.Length | number | Yes | Package length |
Shipments[].Package.Width | number | Yes | Package width |
Shipments[].Package.Height | number | Yes | Package height |
{
"ShipmentID": "ku3027lhufe",
"Reference": "ORDER-56789",
"TrackingNumber": "9299927280",
"LabelUrl": [
"https://cdn.flavorcloud.com/s-ORDER56789-label.pdf"
],
"Carrier": "DHL",
"TrackingUrl": "https://app.flavorcloud.com/brandedTracking?ref=ORDER-56789&tr_no=9299927280&carrier=DHL&destination=London,%20GB",
"SubmittedElectronically": true,
"CustomsInvoiceURL": "https://cdn.flavorcloud.com/s-ORDER56789-invoice.pdf",
"RootRequestId": "62073634-c180-4d0a-8906-ccd940b02cce"
}LabelUrl is an array containing one PDF URL per package. Print and attach the label to the corresponding package.SubmittedElectronically: true means FlavorCloud has filed the commercial invoice electronically with the carrier. You do not need to print and attach the invoice. If SubmittedElectronically is false, you must print and attach the CustomsInvoiceURL document to the package.SubmittedElectronically is false, the PDF at LabelUrl will be a merged 2-page document: page 1 is the label, page 2 is the commercial invoice.POST /Rates and POST /Shipments endpoints as standard outbound shipments. The differences are a handful of additional fields and a change to how you describe the parties and the purpose of the shipment.| Area | B2C | B2B |
|---|---|---|
ShipFromAddress.Name / ShipToAddress.Name | Individual name | Business name |
AttentionName | Recipient name | Specific contact or department (e.g., "Receiving Department") |
ReasonForExport | merchandise | Sold / Commercial Transaction |
B2b flag | Not used | Set to true |
| Tax IDs | Not required | FederalTaxId and/or StateTaxId in ShipToAddress |
| Insurance | Optional | Strongly recommended for high-value shipments |
/Rates for B2BReasonForExport to "Sold / Commercial Transaction" and ensure both Name fields are business names./Shipments for B2B/Shipments request body:B2b: true — Flags this as a B2B shipment. Drives the correct commercial invoice language and customs entry type. If no ReasonForExport is passed but B2b is true, FlavorCloud defaults to Sold / Commercial Transaction.ShipToAddress.FederalTaxId — The consignee's country-level tax ID (e.g., Canada Business Number "123456789RP0001", UK EORI, EU VAT number). Providing this reduces customs delays and is required for accurate import compliance when FlavorCloud acts as Importer of Record.ShipToAddress.StateTaxId (optional) — State or province tax ID, where applicable.LocationName (optional) — Origin warehouse or DC identifier (e.g., "SanFrancisco-CA-1"). Useful when shipping from multiple fulfillment locations.{
"Reference": "B2B-ORDER-001",
"ServiceCode": "STANDARD",
"TermsOfTrade": "DDP",
"ReasonForExport": "Sold / Commercial Transaction",
"B2b": true,
"LocationName": "SanFrancisco-CA-1",
"HashKey": "a893h52k-...",
"DutyHashKey": "h23dj97f-...",
"ShipFromAddress": {
"Name": "The Tap Inc.",
"AttentionName": "Jimmy Owens",
"..."
},
"ShipToAddress": {
"Name": "American Retail",
"AttentionName": "Receiving Department",
"FederalTaxId": "123456789RP0001",
"..."
},
"Shipments": [...]
}DDP is strongly recommended for new B2B relationships. It covers duties, taxes, and fees upfront, preventing surprise costs for the consignee and simplifying customs clearance.
Zero duties in the response? DutyandSalesTaxof0inLandedCostDetailmeans the shipment falls below the destination country's de minimis threshold. This is expected.
| Field | Location | Type | Required | Description |
|---|---|---|---|---|
B2b | Request body | boolean | Yes | Set true to flag as B2B |
LocationName | Request body | string | No | Origin location/warehouse identifier |
ShipToAddress.FederalTaxId | ShipToAddress | string | Recommended | Consignee's country-level tax ID (BN, VAT, EORI, etc.) |
ShipToAddress.StateTaxId | ShipToAddress | string | No | Consignee's state/province tax ID |
Piece[].SKU | Piece items | string | No | Your internal product SKU |
POST /Rates and POST /Shipments endpoints as outbound shipments with three differences:IsReturn: "Y"/Rates response is keyed by carrier name, not service level/Shipments call requires ShipmentKey (the original outbound ShipmentID) and TermsOfTrade: "DDU"All returns are DDU. International returns travel duty-free back to the sender — FlavorCloud enforces DDU on all return shipments.
Prerequisites: You need the ShipmentIDfrom the original outbound/Shipmentsresponse. Contact FlavorCloud support if you need to look it up.
ShipFromAddress and ShipToAddress in the same order as the original outbound shipment. FlavorCloud reverses the shipping direction on the return label automatically."DHL Express Worldwide") rather than by service level (Express / Standard). Your parsing logic must handle both structures.ShipmentKey: Pass the original outbound ShipmentID as ShipmentKey in the return /Shipments request to link the return to its outbound shipment.Reference: Use the same Reference as the original outbound shipment.POST /RatesHeaders required: Content-Type: application/jsonandAuthorization: <your JWT token>
{
"Reference": "ORDER-56789",
"WeightUnit": "LB",
"DimensionUnit": "IN",
"Currency": "USD",
"IsReturn": "Y",
"ReasonForExport": "return",
"ShipFromAddress": { "..." },
"ShipToAddress": { "..." },
"Pieces": [{ "..." }],
"Package": { "Weight": 1.25 }
}{
"RateId": 7234111,
"Reference": "ORDER-56789",
"Currency": "USD",
"DHL Express Worldwide": {
"DDU": {
"HashKey": "Z1R3zB7",
"ShippingCost": 28.50,
"Days": "0-1 business days",
"Carrier": "DHL"
}
},
"InXpress Express Worldwide": {
"DDU": {
"HashKey": "AWrmo",
"ShippingCost": 22.00,
"Days": "1-2 business days",
"Carrier": "inXpress"
}
},
"RootRequestId": "588299cd-..."
}Null shipping costs: ShippingCostmay benullfor some carriers — this means pricing is confirmed at pickup. TheHashKeyis still valid and required.
POST /ShipmentsHeaders required: Content-Type: application/jsonandAuthorization: <your JWT token>
{
"Reference": "ORDER-56789",
"ServiceCode": "STANDARD",
"TermsOfTrade": "DDU",
"IsReturn": "Y",
"ReasonForExport": "return",
"ShipmentKey": "ku3027lhufe",
"HashKey": "Z1R3zB7",
"ShipFromAddress": { "..." },
"ShipToAddress": { "..." },
"Shipments": [{ "..." }]
}LabelUrl PDF will contain a return label with addresses already reversed — provide it to the customer to attach to the package.| Field | Type | Required | Description |
|---|---|---|---|
IsReturn | string | Yes | Set "Y" on both the /Rates and /Shipments calls |
ShipmentKey | string | Yes | The ShipmentID from the original outbound /Shipments response |
TermsOfTrade | string | Yes | Must be "DDU" for all returns |
ReasonForExport | string | Yes | Use "return" for return shipments |
POST https://partnerapi.flavorcloud.com/Webhooks/SubscribeTip: Use Webhook.site (or a similar tool) to inspect webhook payloads during development.
| Event Name | Trigger |
|---|---|
SHIPMENT_CREATED | A shipment label has been successfully generated |
TRACKING_UPDATES | A tracking status update has been received from the carrier |
Headers required: Content-Type: application/jsonandAuthorization: <your JWT token>
{
"WebHooksList": [
{
"EventName": "SHIPMENT_CREATED",
"URL": "https://your-system.example.com/webhooks/flavorcloud"
},
{
"EventName": "TRACKING_UPDATES",
"URL": "https://your-system.example.com/webhooks/flavorcloud"
}
]
}{
"Status": "Success",
"Message": "Subscribed successfully",
"RootRequestId": "98282373-558b-4d4a-96f1-68adf1a35b5d"
}{
"event": "shipment-created",
"shipment_id": "ku3027lhufe",
"tracking_number": "9299927280",
"reference": "ORDER-56789",
"carrier": "DHL",
"label_url": "https://cdn.flavorcloud.com/s-ORDER56789-label.pdf"
}{
"event": "tracking-updates",
"tracking_number": 9299927280,
"app_id": "your_app_id_here",
"shipment_id": "ku3027lhufe",
"tracking_history": [
{
"status": "In Transit",
"status_detail": "Shipment arrived at DHL sort facility",
"status_date": "2025-04-16 09:22:00",
"location": "East Midlands, UK",
"country": "United Kingdom"
},
{
"status": "In Progress",
"status_detail": "Shipment created and label generated",
"status_date": "2025-04-15 14:00:00",
"location": "San Francisco, CA",
"country": "United States"
}
]
}Casing note: Webhook payloads use snake_casefield names (e.g.,tracking_number,status_detail). This differs from the REST API responses, which usePascalCase(e.g.,TrackingNumber,StatusDetail). Ensure your webhook receiver handlessnake_caseparsing.
| Status | Meaning |
|---|---|
In Progress | Label created; package not yet with carrier |
In Transit | Package is with the carrier en route to destination |
Delivered | Carrier has confirmed delivery |
GET https://partnerapi.flavorcloud.com/Tracking/Get/Detail/{TrackingNumber}Authorization header — same as all other endpoints.GET https://partnerapi.flavorcloud.com/Tracking/Get/Detail/9299927280{
"Reference": "ORDER-56789",
"TrackingNumber": "9299927280",
"EstimatedDelivery": "2025-04-18T14:00:00",
"TrackingHistory": [
{
"Location": "East Midlands, UK",
"StatusDate": "2025-04-16T09:22:00",
"StatusDetail": "Shipment arrived at DHL sort facility",
"Status": "In Transit"
},
{
"Location": "",
"StatusDate": "2025-04-15T14:00:00",
"StatusDetail": "Shipment created and label generated",
"Status": "In Progress"
}
],
"RootRequestId": "5a42d525-8541-492c-a2b3-60f0b6d51a17"
}Note: EstimatedDeliverymay be an empty string ("") early in the shipment lifecycle before the carrier has assigned a delivery estimate. Most carriers do not provide this until the package has been physically tendered.
POST https://partnerapi.flavorcloud.com/Webhooks/UnSubscribeHeaders required: Content-Type: application/jsonandAuthorization: <your JWT token>
{
"Events": [
"SHIPMENT_CREATED"
]
}{
"Status": "Success",
"Message": "WebHook Removed",
"RootRequestId": "f662e5be-93dd-4e2b-b3ba-142a8b237826"
}| HTTP Status | Meaning |
|---|---|
200 | Success |
400 | Bad Request — check your request body for missing or invalid fields |
401 | Unauthorized — verify your AppID and RestApiKey |
404 | Not Found — the requested resource (e.g., TrackingNumber) does not exist |
422 | Unprocessable Entity — the request was well-formed but the data was invalid (e.g., unsupported destination country) |
500 | Internal Server Error — contact FlavorCloud support if this persists |
/Rates again to get a fresh key.