Shipper Open API

Integrez votre systeme avec Shipper pour creer et suivre les commandes automatiquement.

v1https://server.shipper.network/api/v1PostmanTelecharger la collection Postman

Premiers pas

L'Open API Shipper est une API REST qui vous permet de :

  • Creer des commandes automatiquement depuis votre systeme
  • Recuperer les details des commandes et le suivi des expeditions
  • Listez et recherchez vos produits et commandes
  • Annulez des commandes par programmation
  • Recevez des mises a jour de statut en temps reel via webhooks

Pour commencer, generez une cle API depuis votre tableau de bord Shipperdans Integrations > API.


Authentification

Toutes les requetes API necessitent un token Bearer dans l'en-tete Authorization.

Authorization: Bearer YOUR_API_KEY
Accept: application/json
Content-Type: application/json
Limites de debit

Les requetes sont limitees par cle API. Depasser la limite retourne HTTP 429 (Too Many Requests).

Type de point d'accesLimitePoints d'acces
Lecture120req/minGET /products, /orders, /orders/:id, /webhooks
Tableau de bord30req/minGET /dashboard/*
Reference60req/minGET /countries, /countries/:code/divisions
Ecriture30req/minPOST /orders, /webhooks
Destructif20req/minPOST /orders/:id/cancel, DELETE /webhooks/:id

Les en-tetes de limite (X-RateLimit-Limit, X-RateLimit-Remaining) sont inclus dans chaque reponse.


Geographie

GETGET /countries

Retourne tous les pays supportes avec leur structure geographique. Utilisez ceci pour comprendre quels niveaux de division (gouvernorat, delegation, etc.) sont requis pour chaque pays.

Exemple de requete
curl https://server.shipper.network/api/v1/countries \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

[
  {
    "code": "TN",
    "name": "Tunisia",
    "geo_structure": {
      "fields": [
        { "id": "division_1_id", "label": "Governorate", "level": 1, "required": true, "depends_on": null },
        { "id": "division_2_id", "label": "Delegation", "level": 2, "required": true, "depends_on": "division_1_id" }
      ]
    }
  }
]

Le tableau geo_structure.fields vous indique combien de niveaux de division existent, leurs libelles et dependances. Utilisez depends_on pour construire des listes en cascade.

GETGET /countries/{code}/divisions

Retourne les noms des divisions pour un pays. Utilisez-le pour obtenir les valeurs valides pour address.division_1 et address.division_2 lors de la creation de commandes.

Parametres de requete
ParametreTypeRequisDescription
levelinteger-Niveau de division (defaut : 1 = niveau superieur)
parent_idinteger-Filtrer par ID de division parente pour obtenir les enfants
Exemple : Divisions de premier niveau
curl https://server.shipper.network/api/v1/countries/TN/divisions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
{
  "country": "TN",
  "geo_structure": { ... },
  "divisions": [
    { "id": 1, "name": "Tunis", "level": 1, "parent_id": null },
    { "id": 2, "name": "Sfax", "level": 1, "parent_id": null },
    { "id": 3, "name": "Sousse", "level": 1, "parent_id": null }
  ]
}
Exemple : Sous-divisions sous un parent
curl "https://server.shipper.network/api/v1/countries/TN/divisions?level=2&parent_id=1" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
{
  "country": "TN",
  "geo_structure": { ... },
  "divisions": [
    { "id": 10, "name": "Bab El Bhar", "level": 2, "parent_id": 1 },
    { "id": 11, "name": "Bab Souika", "level": 2, "parent_id": 1 },
    { "id": 12, "name": "Carthage", "level": 2, "parent_id": 1 }
  ]
}

Produits

GETGET /products

Retourne votre catalogue produits avec les UUIDs. Vous avez besoin des UUIDs pour creer des commandes via l'API.

Parametres de requete
ParametreTypeRequisDescription
pageinteger-Numero de page (defaut : 1)
per_pageinteger-Elements par page (defaut : 20, max : 100)
searchstring-Rechercher par nom de produit ou SKU
Exemple de requete
curl "https://server.shipper.network/api/v1/products?per_page=10&search=shirt" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "data": [
    {
      "uuid": "2e97b37a-3118-4905-842c-19706bcf1455",
      "name": "Blue T-Shirt",
      "sku": "SKU-001",
      "price": 190,
      "cost": 75,
      "status": "active",
      "link": "https://app.shipper.market/products/2e97b37a-3118-4905-842c-19706bcf1455",
      "supplier_identifier": "RU836",
      "available_qte": 42,
      "variants": [
        {
          "uuid": "a1b2c3d4-5678-9012-abcd-ef0123456789",
          "name": "Size L",
          "sku": "SKU-001-L",
          "price": 190,
          "cost": 75,
          "available_qte": 15
        }
      ]
    }
  ],
  "pagination": { "total": 50, "current_page": 1, "per_page": 10, "last_page": 5 }
}
Notes sur les champs de reponse
  • price — votre prix de vente (ce que le client paie), dans la devise de votre organisation.
  • cost — le cout fournisseur (ce que vous payez au fournisseur par unite). Disponible sur le produit et par variante.
  • link — URL Shipper Market partageable pour ce produit (utile pour votre equipe ou le marketing).
  • supplier_identifier — le nom d'utilisateur Shipper du fournisseur (par ex. RU836). Identifie quel fournisseur execute le produit.
  • available_qte — total des unites en stock disponibles dans les entrepots actifs (somme de public_stocks.qte).

GETGET /products/{uuid}

Retourne un produit par UUID, incluant ses variantes et les quantites disponibles en stock.

Exemple de requete
curl https://server.shipper.network/api/v1/products/2e97b37a-3118-4905-842c-19706bcf1455 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "uuid": "2e97b37a-3118-4905-842c-19706bcf1455",
  "name": "Blue T-Shirt",
  "sku": "SKU-001",
  "price": 190,
  "cost": 75,
  "status": "active",
  "link": "https://app.shipper.market/products/2e97b37a-3118-4905-842c-19706bcf1455",
  "supplier_identifier": "RU836",
  "available_qte": 42,
  "variants": [
    { "uuid": "a1b2c3d4-...", "name": "Size L", "sku": "SKU-001-L", "price": 190, "cost": 75, "available_qte": 15 },
    { "uuid": "e5f6a7b8-...", "name": "Size M", "sku": "SKU-001-M", "price": 190, "cost": 75, "available_qte": 27 }
  ]
}

Commandes

GETGET /orders

Retourne une liste paginee de vos commandes. Utilisez les filtres pour affiner par statut, plage de dates ou termes de recherche.

Parametres de requete
ParametreTypeRequisDescription
pageinteger-Numero de page (defaut : 1)
per_pageinteger-Elements par page (defaut : 20, max : 100)
statusstring-Filtrer par statut d'expedition (ex: delivered, awaitingpackaging, canceled)
start_datestring-Filtrer les commandes creees a partir de cette date/heure. Accepte YYYY-MM-DD (interprete comme 00:00:00) ou YYYY-MM-DD HH:MM[:SS] pour une precision a la minute.
end_datestring-Filtrer les commandes creees avant ou egal a cette date/heure. Les saisies date-uniquement (YYYY-MM-DD) incluent toute la journee ; YYYY-MM-DD HH:MM[:SS] pour une precision a la minute.
searchstring-Rechercher par ID de commande, nom du client ou numero de telephone
Exemple de requete
curl "https://server.shipper.network/api/v1/orders?status=delivered&start_date=2026-05-01%2009:00&per_page=10" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "data": [
    {
      "id": 555,
      "status": "Paid",
      "store_name": "My Store",
      "is_cod": true,
      "is_paid": true,
      "created_at": "2026-05-10T10:00:00.000000Z",
      "address": { "first_name": "Omar", "last_name": "Ben Ali", "phone1": "+21628177188" },
      "items_count": 3,
      "shipments_count": 1,
      "products": [
        { "id": 442, "name": "Smart Sensor Light Toilet Lid" }
      ],
      "revenue": "59",
      "external_order_id": "ORD-123",
      "external_order_url": "https://mystore.com/orders/123"
    }
  ],
  "pagination": { "total": 150, "current_page": 1, "per_page": 10, "last_page": 15 }
}
Notes sur les champs de reponse
  • status — calcule a partir des expeditions de la commande. Valeurs possibles : Pending, Fulfilled, In Transit, Delivered, Partial Delivery, Returned, Partial Return, Canceled, Paid. Peut aussi etre null pour les commandes sans expedition.
  • items_count — total des unites commandees (somme des quantites a travers les articles du panier).
  • products — produits distincts du revendeur referencees par la commande. Vide pour les commandes sans execution encore.
  • revenue — somme des transactions de revenus d'expedition du revendeur en statut Successful ou Under Review (c'est-a-dire realises + gagnes-en-attente). Reporte dans la devise de votre organisation, sous forme de chaine decimale simple. Zero jusqu'a ce qu'au moins une expedition soit livree.

POSTPOST /orders

Cree une nouvelle commande dans Shipper. Retourne l'ID de commande que vous pouvez utiliser pour suivre la commande.

Corps de la requete
ParametreTypeRequisDescription
addressobject*Objet adresse du destinataire (voir les champs ci-dessous)
address.namestring*Nom complet - separe automatiquement en prenom et nom
address.phone1string*Numero de telephone principal
address.phone2string-Numero de telephone secondaire
address.address1string*Adresse ligne 1
address.address2string-Adresse ligne 2
address.division_1string-Etat / Gouvernorat - utilisez le nom exact de GET /countries/{code}/divisions
address.division_2string-Ville / Delegation - utilisez le nom exact de GET /countries/{code}/divisions?level=2&parent_id=...
address.countrystring*Code pays a deux lettres (ex: TN, DZ, MA)
itemsarray*Tableau des articles de la commande
items[].idstring*UUID du produit ou de la variante de GET /products
items[].quantityinteger-Quantite (defaut : 1)
items[].total_pricenumber-Prix total pour cette ligne. Par defaut : prix du produit x quantite
shipping_totalnumber-Frais de livraison factures au client (defaut : 0)
is_codboolean-)
auto_fulfillboolean-Envoyer directement en preparation sans creer de brouillon (defaut : false)
with_confirmationboolean-Exiger un appel de confirmation avant l'expedition (defaut : false)
store_namestring-Nom du magasin source - apparait dans le suivi pour votre reference
external_order_idstring-ID de reference de votre systeme - affiche dans le tableau de bord Shipper
external_order_urlstring-URL de la commande dans votre systeme - cliquable depuis le tableau de bord Shipper
Exemple de requete
curl -X POST https://server.shipper.network/api/v1/orders \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "address": {
      "name": "Omar Ben Ali",
      "division_1": "Tunis",
      "division_2": null,
      "phone1": "28177188",
      "address1": "Rue de la Liberte",
      "country": "TN"
    },
    "items": [
      { "quantity": 1, "id": "YOUR_PRODUCT_UUID", "total_price": 190 }
    ],
    "shipping_total": 9,
    "is_cod": true,
    "auto_fulfill": true,
    "with_confirmation": true,
    "store_name": "My Store",
    "external_order_id": "ORD-12345",
    "external_order_url": "https://mystore.com/orders/12345"
  }'
Reponse

201Cree

{
  "id": 555
}

GETGET /orders/{id}

Retourne les details complets de la commande incluant le statut, les numeros de suivi avec les journaux de livraison et l'adresse du destinataire.

Parametres du chemin
ParametreTypeRequisDescription
idinteger*L'ID de commande retourne lors de la creation
Exemple de requete
curl https://server.shipper.network/api/v1/orders/555 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "id": 555,
  "status": "Paid",
  "contact_task_status": "called",
  "shipments": [
    {
      "uuid": "11111111-2222-3333-4444-555555555555",
      "status": "delivered",
      "tracking_numbers": [
        {
          "number": "99999999999",
          "logs": [
            { "status": "at_carrier_origin_facility", "created_at": "2025-01-15T02:02:59.000000Z", "external_timestamp": "2025-01-14 22:48:00" },
            { "status": "in_transit", "created_at": "2025-01-15T02:02:59.000000Z", "external_timestamp": "2025-01-14 23:05:00" },
            { "status": "delivered", "created_at": "2025-01-18T02:09:19.000000Z", "external_timestamp": "2025-01-17 14:16:00" }
          ]
        }
      ]
    }
  ],
  "address": {
    "first_name": "Omar", "last_name": "Ben Ali",
    "phone1": "+21628177188", "phone2": "",
    "address1": "Rue de la Liberte", "address2": "",
    "division_1": "Tunis", "division_2": null, "country": "TN"
  }
}

POSTPOST /orders/{id}/cancel

Annule une commande et ses expeditions associees. Fonctionne pour les commandes en phase de confirmation (en attente de confirmation telephonique) ou en phase de preparation (en attente d'emballage). Les commandes deja expediees ne peuvent pas etre annulees via l'API.

Parametres du chemin
ParametreTypeRequisDescription
idinteger*L'ID de la commande a annuler
Exemple de requete
curl -X POST https://server.shipper.network/api/v1/orders/555/cancel \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "success": true,
  "canceled_shipments": 1
}
Reponse d'erreur

422Si aucune expedition ne peut etre annulee :

{
  "error": "No shipments available to cancel"
}

Tableau de bord

Endpoints de statistiques agregees qui alimentent le tableau de bord du revendeur. Toutes les routes necessitent un token API d'organisation revendeur ; les tokens non-revendeurs recoivent un HTTP 403.

GETGET /dashboard/overview

Repartition revenus / depenses / benefice pour les expeditions, groupee par statut (en attente, livree-payee, livree-non-payee, livraison-echouee). Chaque groupe expose des repartitions de depenses par poste et des sous-totaux par type de commande.

Exemple de requete
curl "https://server.shipper.network/api/v1/dashboard/overview?start_date=2026-04-01&end_date=2026-04-30" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "shipments_pending":            { /* StatusGroup, see below */ },
  "shipments_delivered_paid":     { ... },
  "shipments_delivered_non_paid": { ... },
  "shipments_failed_delivery":    { ... },
  "stats_by_order_type": [
    {
      "order_type": "dropshipping",
      "shipments_pending":            { ... },
      "shipments_delivered_paid":     { ... },
      "shipments_delivered_non_paid": { ... },
      "shipments_failed_delivery":    { ... }
    }
  ]
}
Forme du StatusGroup
{
  "status": "shipments_delivered_paid",
  "count": 133,
  "orders_with_revenue_count": 129,
  "revenue":              [{ "amount": "9750.00", "currency": { "id": "1", "ISO_4217": "TND", "symbol": "د.ت", "decimals": 3 } }],
  "revenue_expected":     [...],
  "revenue_transferred":  [...],
  "expenses":             [...],
  "expenses_transferred": [...],
  "expenses_expected":    [...],
  "net_profits":          [...],
  "expenses_breakdown": {
    "shipping":         [...],
    "packaging":        [...],
    "service":          [...],
    "qc":               [...],
    "payment_facility": [...],
    "confirmation":     [...],
    "call_forwarding":  [...],
    "follow_up":        [...],
    "upsell":           [...],
    "prepaid_cost":     [...],
    "product_cost":     [...],
    "dropshipping_fee": [...],
    "return_exchange_fee": [...]
  },
  "expenses_breakdown_transferred": { /* same 13 keys */ }
}

Les champs monetaires sont des tableaux de {amount, currency} pour la compatibilite future avec les revendeurs multi-devises ; aujourd'hui une seule entree est renvoyee dans la devise par defaut de l'organisation. Les montants sont des chaines decimales pour preserver la precision (les transactions stockent decimal(65,30)).

GETGET /dashboard/delivery-stats

Nombres par statut d'expedition, repartition des motifs d'echec de livraison, et KPIs de vitesse de livraison en jours ouvres. Limite aux commandes dropshipping.

Exemple de requete
curl "https://server.shipper.network/api/v1/dashboard/delivery-stats?start_date=2026-04-01&end_date=2026-04-30" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "total_by_status": [
    { "status": "delivered", "count": 4843, "on_hold_count": 0 },
    { "status": "canceled",  "count": 238,  "on_hold_count": 0 },
    { "status": "returnedtosender", "count": 28, "on_hold_count": 0 }
  ],
  "total_delivery_failures_by_reason": [
    { "reason": "Customer unavailable for delivery", "count": 993 },
    { "reason": "Trust or credibility issues at delivery", "count": 136 },
    { "reason": null, "count": 565 }
  ],
  "avg_delivery_speed_business_days": 1.6,
  "max_delivery_speed_business_days": 28,
  "delivered_within_1bd_pct": 66.3,
  "delivered_within_2bd_pct": 21,
  "delivered_over_2bd_pct":   12.7
}

GETGET /dashboard/confirmation-stats

Statistiques d'entonnoir de prospects et de conversion en livraison pour les commandes confirmees par un service de confirmation Shipper externe.

Exemple de requete
curl "https://server.shipper.network/api/v1/dashboard/confirmation-stats?start_date=2026-04-01&end_date=2026-04-30" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "has_stats": true,
  "stats": {
    "leads": {
      "total": 5484,
      "confirmed": 3371,
      "failed": 599,
      "closed_unreachable": 1068,
      "closed_unconfirmed": 445,
      "under_process": 1,
      "no_attempt": 0
    },
    "delivery_rates": {
      "delivered": 2240,
      "failed": 1072,
      "returning": 13,
      "in_transit": 8,
      "not_shipped": 12,
      "total_pipeline": 3345,
      "total_final": 3312,
      "overall_rate": 66.97,
      "absolute_rate": 67.63
    }
  }
}

has_stats est false lorsque l'organisation n'a aucune commande routee via confirmation externe ; stats sera null dans ce cas.

GETGET /dashboard/internal-confirmation-stats

Meme forme que /dashboard/confirmation-stats, mais limite aux commandes confirmees en interne par le revendeur (sans service de confirmation Shipper). Utile pour les revendeurs qui executent les deux flux en parallele.

Exemple de requete
curl "https://server.shipper.network/api/v1/dashboard/internal-confirmation-stats" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200 — forme identique a /dashboard/confirmation-stats. Lorsque le revendeur n'a aucune commande confirmee en interne, has_stats est false et stats est null :

{
  "has_stats": false,
  "stats": null
}

GETGET /dashboard/product-performance

Performance par produit, paginee et triable : nombres et unites d'expedition par statut, plus entonnoir de confirmation par produit et les memes regroupements par statut que /dashboard/overview.

Parametres de requete
ParametreTypeRequisDescription
pageinteger-Numero de page (defaut : 1)
per_pageinteger-Elements par page (defaut : 20, max : 50)
sort_bystring-L'une des valeurs : shipped_orders, delivered_orders, failed_orders, confirmed_return_orders, in_transit_orders, returning_orders, leads_total, leads_confirmed, overall_confirmation_rate, absolute_confirmation_rate, conversion_rate. Defaut : shipped_orders. Les valeurs invalides renvoient 422.
start_datestring-Filtre de date optionnel (voir l'introduction du Tableau de bord).
end_datestring-Filtre de date optionnel (voir l'introduction du Tableau de bord).
retailer_product_idinteger-Limiter a un seul produit du revendeur.
Exemple de requete
curl "https://server.shipper.network/api/v1/dashboard/product-performance?per_page=10&sort_by=delivered_orders" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{
  "products": [
    {
      "retailer_product_id": "550",
      "name": "SMOKURE STOP TABAC 40 CAPSULES",
      "shipped_orders": 2351,   "shipped_units": 2418,
      "delivered_orders": 1442, "delivered_units": 1487,
      "failed_orders": 898,     "failed_units": 921,
      "in_transit_orders": 12,  "in_transit_units": 13,
      "returning_orders": 4,    "returning_units": 4,
      "confirmed_return_orders": 320, "confirmed_return_units": 327,
      "leads_total": 3531,
      "leads_confirmed": 2374,
      "leads_failed": 121,
      "leads_unreachable": 715,
      "leads_duplicate_wrong": 18,
      "leads_closed_other": 303,
      "overall_confirmation_rate": 67.2,
      "absolute_confirmation_rate": 70.5,
      "conversion_rate": 40.8,
      "shipments_pending":            { /* StatusGroup */ },
      "shipments_delivered_paid":     { ... },
      "shipments_delivered_non_paid": { ... },
      "shipments_failed_delivery":    { ... }
    }
  ],
  "total": 127
}

La pagination est pilotee par page/per_page ; la reponse ne contient que le total. Calculez last_page comme Math.ceil(total / per_page).


Webhooks

Les webhooks vous permettent de recevoir des notifications HTTP en temps reel lors des changements de statut, au lieu d'interroger l'API.

POSTPOST /webhooks

Enregistrez une URL pour recevoir les evenements webhook. Vous pouvez enregistrer jusqu'a 5 webhooks par cle API. L'URL doit utiliser HTTPS.

Corps de la requete
ParametreTypeRequisDescription
urlstring*URL HTTPS qui recevra les requetes POST avec les donnees d'evenement
eventsarray*Evenements : "order.status_changed" et/ou "shipment.status_changed"
secretstring-Cle secrete (min 16 caracteres) utilisee pour signer les donnees avec HMAC-SHA256
Exemple de requete
curl -X POST https://server.shipper.network/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mystore.com/webhooks/shipper",
    "events": ["order.status_changed", "shipment.status_changed"],
    "secret": "my-webhook-secret-key"
  }'
Reponse

201

{
  "id": 1,
  "url": "https://mystore.com/webhooks/shipper",
  "events": ["order.status_changed", "shipment.status_changed"],
  "status": "active",
  "created_at": "2025-03-29T10:00:00.000000Z"
}

GETGET /webhooks

Retourne tous les webhooks enregistres pour la cle API actuelle, incluant leur statut et le nombre d'echecs.

Exemple de requete
curl https://server.shipper.network/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

[
  {
    "id": 1,
    "url": "https://mystore.com/webhooks/shipper",
    "events": ["order.status_changed", "shipment.status_changed"],
    "status": "active",
    "last_triggered_at": "2025-03-29T15:30:00.000000Z",
    "failure_count": 0,
    "created_at": "2025-03-29T10:00:00.000000Z"
  }
]

DELETEDELETE /webhooks/{id}

Supprime un enregistrement webhook. Le webhook cessera de recevoir les evenements immediatement.

Exemple de requete
curl -X DELETE https://server.shipper.network/api/v1/webhooks/1 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
Reponse

200

{ "success": true }

Format du contenu Webhook

Lorsqu'un evenement se produit, Shipper envoie une requete POST a votre URL enregistree avec un corps JSON :

order.status_changed
{
  "event": "order.status_changed",
  "timestamp": "2025-01-15T10:30:00.000000Z",
  "data": {
    "order_id": 555,
    "status": "Paid",
    "previous_status": "Pending"
  }
}
shipment.status_changed
{
  "event": "shipment.status_changed",
  "timestamp": "2025-01-15T10:30:00.000000Z",
  "data": {
    "order_id": 555,
    "shipment_uuid": "11111111-2222-3333-4444-555555555555",
    "status": "delivered",
    "previous_status": "onitsway"
  }
}
Verification de la signature

Si vous avez fourni un secret lors de l'enregistrement, chaque requete inclut un en-tete X-Shipper-Signature. Verifiez-le en calculant le HMAC-SHA256 du corps brut avec votre secret :

// Node.js example
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', 'my-webhook-secret-key')
  .update(rawBody)
  .digest('hex');
const isValid = signature === req.headers['x-shipper-signature'];

Codes d'erreur

L'API utilise les codes de statut HTTP standards. Toutes les reponses d'erreur incluent un corps JSON avec les details.

CodeSignification
200Succes
201Ressource creee avec succes
401Non autorise - cle API manquante ou invalide
403Interdit - cle API desactivee ou revoquee
404Non trouve - la ressource demandee n'existe pas
422Erreur de validation - verifiez l'objet errors dans le corps de la reponse
429Trop de requetes - limite de debit depassee. Attendez et reessayez