Migrating from API v2
The API v2 (/api/v2/*, /api/v2.1/*), the Basic-auth /api/v1/* and /api/tracking/{ldv} are deprecated since 3 September 2026 and will be retired on 28 February 2027. Until then they keep working unchanged; every response carries:
Deprecation: @1788393600
Sunset: Sun, 28 Feb 2027 23:59:59 GMT
Link: <https://<subdomain>.spedisci.online/api/2026-09>; rel="successor-version", <https://apidocs.spedisci.online>; rel="deprecation"The driver app endpoints (/api/v2/driver/*) are not affected.
What changes
| API v2 | Client API 2026-09 | |
|---|---|---|
| Base URL | /api/v2/ | /api/2026-09/ |
| Authentication | Static API key as bearer token | OAuth2 token (1 hour) from an App’s client_id / client_secret — see Authentication |
| Style | RPC-like POST endpoints | REST resources, GET/POST/PUT/DELETE |
| Field names | Mixed (shipFrom, codValue, label_format, rif_dest…) | camelCase with typed value objects (Money, Weight, Dimensions) |
| Units | Implicit kg / cm | Explicit units (KG/G, CM/MM) |
| Errors | Various shapes, HTTP 400/405/501 | One envelope { "error": { "code", "message", "details" } } with stable codes — see Conventions |
| Lists | Arrays | { "data": [...] }, paginated with per_page / page |
| Statuses | Numeric | { "code", "key", "label" } |
| Tenancy | Every resource is scoped to the client of the token; other clients’ resources are 404 |
Endpoint mapping
| API v2 | Client API 2026-09 | Notes |
|---|---|---|
POST /shipping/rates | POST /rates | Response is { "data": [...] }; prices are numbers under price.total / price.breakdown |
POST /shipping/create | POST /shipments | Returns 201 with the full shipment and label.pdf / label.zpl |
POST /shipping/delete | DELETE /shipments/{ldv} | Addressed by tracking number |
| — | GET /shipments, GET /shipments/{ldv}, GET /shipments/{ldv}/label | New |
GET /tracking/{ldv} | GET /shipments/{ldv}/tracking | Normalized events with ISO timestamps |
POST /shippinglist/create | POST /manifests | Returns one manifest per contract with the PDF |
POST /pickup/create | POST /pickups | |
| Open stocks list | GET /stocks | |
POST /stock/update | POST /stocks/{id}/actions | Addressed by stock id, action names instead of numeric codes |
| Webhooks page | /webhooks | Same signature; endpoints can now be registered through the API |
| Carriers catalogue | GET /carriers | Now returns only the contracts of the client |
Field mapping for shipment creation
API v2 (/shipping/create) | 2026-09 (POST /shipments) |
|---|---|
carrierCode | carrierCode (optional consistency check) |
contractCode | serviceType |
label_format | options.labelFormat |
packages[].length/width/height/weight | packages[].dimensions{length,width,height,units} + packages[].weight{value,units} |
shipFrom | shipper |
shipTo | recipient |
street1 / street2 | address.street / address.street2 |
state | address.province |
country | address.countryCode |
notes | options.notes |
content | options.contentDescription |
insuranceValue | options.insurance.amount |
codValue | options.cod.amount |
cashOnDeliveryMode | options.cod.method |
codType | options.cod.type |
accessoriServices | options.accessoryServices[] (service ids) |
order_id | reference |
rif_dest | recipient.reference |
order_total | packages[].value / customsDetail.customsValue |
| — | customsDetail (new, required outside the EU customs territory) |
| API v2 response | 2026-09 response |
|---|---|
shipmentId | id |
trackingNumber | trackingNumber |
shipmentCost (string) | cost.total (number) |
packages[].pack_number | packages[].number |
labelData | label.pdf |
labelZPL | label.zpl |
Migration checklist
- Create an App in Settings → API App and implement the
client_credentialstoken request with caching and renewal on401. - Replace the base URL and the
Authorizationheader source. - Map the request payloads with the tables above; add explicit
units. - Handle the new error envelope: branch on
error.code, showerror.message, read field errors inerror.details. - Add
customsDetailfor non-EU destinations, or complete the customs defaults of your product catalog in the web interface. - Move status polling to webhooks where possible.
- Test against your account, then switch. Keep the v2 code path only until the switch is verified.
Existing webhook endpoints keep working: the tracking.update payload is unchanged apart from the added event and timestamp fields.
Last updated on