Skip to Content
Client API 2026-09Conventions & Errors

Conventions & Errors

Requests

  • Send Accept: application/json on every request and Content-Type: application/json when the request has a body.
  • Path parameters {ldv} are tracking numbers (LDV), {id} are numeric identifiers, {bda} a BDA.
  • Boolean query parameters accept true/false and 1/0.
  • Dates in query parameters and request bodies use YYYY-MM-DD.

Responses

Responses are always JSON (Content-Type: application/json), including errors.

  • A single resource is returned as a bare object.
  • A collection is returned as { "data": [...] }. Large collections are paginated:
{ "data": [ ... ], "links": { "first": "...?page=1", "last": "...?page=8", "prev": null, "next": "...?page=2" }, "meta": { "current_page": 1, "from": 1, "last_page": 8, "per_page": 50, "to": 50, "total": 391 } }
Query parameterDefaultMaxDescription
per_page50200Items per page
page1Page number

Lists are ordered from the most recent item.

Value objects

The same structures are used everywhere, in requests and responses.

ObjectShapeNotes
Date / time"2026-09-03T10:26:54+02:00"ISO 8601 with time zone offset
Money{ "amount": 12.5, "currency": "EUR" }currency is optional in requests (default EUR)
Weight{ "value": 1.5, "units": "KG" }Requests accept KG or G (default KG); responses always use KG
Dimensions{ "length": 30, "width": 20, "height": 10, "units": "CM" }Requests accept CM or MM (default CM); responses always use CM
Address{ "street", "street2", "city", "province", "postalCode", "countryCode" }countryCode ISO 3166-1 alpha-2; province is the 2-letter code for Italy
Party{ "name", "company", "address": Address, "phone", "email", "reference" }Shipper, recipient, pickup address
Carrier{ "code": "fedex", "name": "FedEx", "contractCode": "...", "contractName": "..." }code is the lowercase carrier identifier
Status{ "code": 5, "key": "delivered", "label": "Consegnata" }See below; label is the Italian label shown in the web UI

Shipment statuses

codekeyMeaning
0, 1processingCreated, not yet handed to the carrier
2shippedShipped
3in_transitIn transit
4out_for_deliveryOut for delivery
5deliveredDelivered
6held_at_depotHeld at depot (a stock / giacenza is open)
7returned_to_senderReturned to sender
8undeliveredNot delivered
9awaiting_instructionsWaiting for the client’s instructions
10awaiting_collectionWaiting for collection at a pickup point

Where a filter accepts a status (for example GET /shipments?status=), you can pass a key, a numeric code or a comma-separated mix: status=delivered,held_at_depot or status=5,6.

Errors

Every error uses the same envelope. code is stable and machine-readable, message is for humans (and may be localized), details is optional (field errors, carrier response, plan limits…).

{ "error": { "code": "validation_failed", "message": "The given data was invalid.", "details": { "recipient.address.postalCode": ["The recipient.address.postal code field is required."] } } }
HTTPcodeWhen
401unauthenticatedToken missing, expired or revoked
402subscription_required · subscription_payment_failed · plan_limit_reachedNo subscription, unpaid subscription or monthly plan limit reached. Only on endpoints that generate costs (POST /shipments, POST /pickups) and on POST /webhooks. details carries plan_limit and shipments_this_month
403insufficient_scope · account_disabled · client_role_required · forbiddenToken or user not authorized; forbidden also when a contract code was issued to another account
404not_foundResource does not exist or belongs to another client; also no contract available for a shipment
405method_not_allowed
409invalid_stateThe operation is no longer possible (shipment already in a manifest or in transit, stock already instructed)
422validation_failedInvalid payload; details maps each field (dot notation) to its messages
422shipment_rejectedThe shipment or pickup was refused by the business rules or by the carrier; the reason is in message
429rate_limitedToo many requests — see the limits below
502carrier_errorThe carrier or an external service did not answer
503http_errorService temporarily unavailable
500internal_errorUnexpected error — retry later, contact support if it persists

A 404 on a resource you just created almost always means you are calling with a token of a different client account (a different App or user). Resources are never shared across accounts.

Rate limits

Limits are per App, per minute. Exceeding one answers 429 rate_limited with the standard Retry-After / X-RateLimit-* headers.

EndpointLimit
POST /rates60 / min
POST /shipments30 / min
POST /pickups10 / min
POST /manifests5 / min
GET /shipments/{ldv}/tracking, GET /tracking/bda/{bda}20 / min (platform setting)
GET /delivery-points30 / min
GET /taric60 / min
POST /webhooks/{id}/test5 / min

For status updates prefer webhooks over polling the tracking endpoints.

Last updated on