Skip to content

Table des matières

Documentation de l'API Publique ShaQ Express

Bienvenue sur l'API Publique ShaQ Express. Cette documentation fournit aux partenaires et aux développeurs les points de terminaison nécessaires pour gérer les colis, les expéditions et recevoir des mises à jour de suivi.

Info Valeur
version 1.0
URL de base (Dév) https://test-partner.shaqexpress.com/api/v1

En-têtes Standard

Toutes les requêtes envoyées à l'API doivent contenir les en-têtes HTTP standard suivants :

En-tête Type Description
Content-Type application/json Nécessite des corps de requête en JSON
Accept application/json Attend des corps de réponse en JSON

(Remarque : Les points de terminaison protégés nécessiteront également un en-tête Authorization: Bearer <token>, que vous obtenez en vous connectant).


Statuts des Colis

Notre système utilise différents statuts pour suivre le cycle de vie d'un colis. Voici la liste complète des statuts que vous pouvez recevoir :

📦 En Attente & Collecte

  • pending : Le colis n'a pas encore été reçu du Partenaire
  • received : Le colis a été reçu du Partenaire
  • warehouse_received : Le colis a été reçu dans un entrepôt régional
  • collected : Le colis a été collecté auprès du Partenaire par ShaQ Express
  • ready_for_pickup : Le colis est prêt pour le retrait par le client

🚚 Transit & Expédition

  • shipped : Le colis a été expédié par le Partenaire
  • assigned : Le colis a été assigné à un Livreur
  • in_transit : Le colis est en transit vers l'entrepôt le plus proche
  • dispatched : Le colis est en route pour être livré

✅ Résultats de Livraison

  • confirmed : Le client a été appelé et la livraison confirmée
  • delivered : Le colis a été livré avec succès au client

⚠️ Problèmes & Exceptions

  • not_delivered : Tentative de livraison échouée
  • rescheduled : La livraison du colis a été replanifiée pour une nouvelle tentative
  • customer_hold : La livraison est en attente à la demande du client
  • customer_unreachable : La livraison est en attente car le client est injoignable
  • suspected_scam : La livraison est en attente en raison d'une suspicion de fraude

🔙 Retours

  • return_picked : Le colis a été récupéré chez le client pour retour au partenaire
  • return_in_progress : Le colis est en cours de préparation pour être renvoyé au Partenaire
  • returned_to_sender : Le colis a été renvoyé au Partenaire
  • return_to_central : Le colis est renvoyé à l'entrepôt central de ShaQ Express après plusieurs tentatives de livraison infructueuses, en préparation du retour au partenaire

Points de Terminaison API

Connexion

POST /auth/login

Obtenir un jeton d'authentification pour les requêtes suivantes. Par mesure de sécurité, le jeton est valide pendant 7 jours, après quoi un nouveau devra être généré via la route /auth/login.

Requête

Paramètre Type Description
identifier string obligatoire.
secret string obligatoire.

Réponse

200

{
  "message": "Request successful",
  "data": {
    "token": "UtXdU9HODhjdmtTNkRtUWNsVlM4OWI1d2Z2TXVIanlkRk"
  }
}

Obtenir les Colis

GET /packages?page=1&limit=1

Obtenir tous les colis

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Request successful",
  "data": {
    "list": [
      {
        "partnerRef": "FGVHKJ567",
        "trackingNumber": "20250410X51DIQ",
        "customerName": "Kwaku Ananse",
        "customerPhone1": "+233244100200",
        "customerPhone2": null,
        "destinationRegion": "Greater Accra",
        "destinationCity": "Accra",
        "status": "delivered",
        "value": "300.00",
        "amountToCollect": "300.00",
        "date": "2025-04-10T11:15:00.000+00:00"
      },
      {
        "partnerRef": "XYZABC123",
        "trackingNumber": "20250410Y62EJR",
        "customerName": "Ama Serwaa",
        "customerPhone1": "+233244200300",
        "customerPhone2": null,
        "destinationRegion": "Ashanti",
        "destinationCity": "Kumasi",
        "status": "pending",
        "value": "150.00",
        "amountToCollect": "150.00",
        "date": "2025-04-11T09:30:00.000+00:00"
      }
    ],
    "meta": {
      "total": 2,
      "perPage": 15,
      "currentPage": 1,
      "lastPage": 1
    }
  }
}

Obtenir un Colis Spécifique

GET /packages/{partnerRef}

Obtenir les détails d'un colis

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Request successful",
  "data": {
    "partnerRef": "FGVHKJ567",
    "trackingNumber": "20250410X51DIQ",
    "customerName": "Kwaku Ananse",
    "customerPhone1": "+233244100200",
    "customerPhone2": null,
    "altPhone": null,
    "destinationRegion": "Greater Accra",
    "destinationCity": "Accra",
    "destinationAddressLine1": "UPSA Hall, Room 3",
    "destinationAddressLine2": null,
    "length": 0,
    "height": 5,
    "weight": 1.2,
    "description": "iPhone 16 pro max black edge silver back casing",
    "units": 1,
    "type": "box",
    "value": "300.00",
    "amountToCollect": "300.00",
    "paymentCollector": "shaq",
    "paymentStatus": "unpaid",
    "handling": "normal",
    "specialInstructions": null,
    "status": "not_delivered",
    "statusDescription": "Attempted delivery but couldn't complete it.",
    "latitude": null,
    "longitude": null,
    "proofPhotoUrl": "https://debtufr1vwh35.cloudfront.net/labels_test/label/8B73CE6D.png",
    "receivedAt": "Jul 15 2025",
    "isReplacement": false,
    "action": null,
    "items": [
      {
        "name": "iPhone 6",
        "quantity": 1
      },
      {
        "name": "iPhone 14 Pro",
        "quantity": 2
      }
    ],
    "rescheduledDate": null,
    "deliveredAt": null,
    "eta": "2026-04-20 - 2026-04-22",
    "maxEta": 5,
    "deliveryAttempts": 1,
    "fulfillmentStage": null,
    "fulfillmentStatus": null,
    "pickedAt": null,
    "packedAt": null,
    "cancelledAt": null,
    "trackingHistory": [
      {
        "name": "not_delivered",
        "description": "Attempted delivery but couldn't complete it.",
        "date": "2025-07-16T09:00:00.000+00:00",
        "comment": "Customer was unreachable upon arrival. Package rescheduled for 2nd delivery attempt."
      },
      {
        "name": "dispatched",
        "description": "Package is en-route to deliver.",
        "date": "2025-07-15T15:45:00.000+00:00",
        "comment": null
      },
      {
        "name": "confirmed",
        "description": "Customer has been called and delivery confirmed.",
        "date": "2025-07-15T15:45:00.000+00:00",
        "comment": null
      },
      {
        "name": "received",
        "description": "Package has been received from Partner.",
        "date": "2025-07-15T15:38:00.000+00:00",
        "comment": null
      },
      {
        "name": "pending",
        "description": "Package is yet to be received by Partner.",
        "date": "2025-07-14T10:38:00.000+00:00",
        "comment": null
      }
    ],
    "callLogs": [
      {
        "phone": "+233244100200",
        "outcome": "answered",
        "comment": "Customer confirmed delivery for tomorrow",
        "date": "2025-07-15 14:30"
      }
    ]
  }
}

Supprimer un Colis en Attente

DELETE /packages/{partnerRef}

Supprimer un colis. Seuls les colis en attente peuvent être supprimés.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Package deleted",
  "data": null
}

Annuler une Commande

POST /packages/{partnerRef}/cancel

Annuler une commande d'exécution.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Order cancelled successfully",
  "data": null
}

400

{
  "message": "Order cannot be cancelled. Order cancellation failed",
  "data": null
}

404

{
  "message": "Order not found",
  "data": null
}

Créer un Colis Unique

POST /packages

Créer un seul colis

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Requête

Paramètre Type Description
partner_ref string obligatoire. Doit être unique.
customer_name string obligatoire.
customer_phone_1 string obligatoire.
customer_phone_2 string optionnel.
source_address_line_1 string obligatoire.
source_address_line_2 string optionnel.
destination_region string obligatoire si region_id est vide.
destination_city string obligatoire.
destination_address_line_1 string obligatoire.
destination_address_line_2 string optionnel.
destination_postal_code string optionnel.
length decimal optionnel.
height decimal optionnel.
weight decimal optionnel.
description string obligatoire.
units number obligatoire.
type string obligatoire . parmi parcel, box
handling string obligatoire . parmi normal, fragile
special_instructions string optionnel.
latitude decimal optionnel.
longitude decimal optionnel.
value decimal obligatoire.
amount_to_collect decimal optionnel. Par défaut, égal à la value du colis.
items array obligatoire. {name, quantity}
landmark string optionnel.
region_id integer obligatoire si destination_region est vide.

Réponse

200

{
  "message": "Package created successfully",
  "data": {
    "partnerRef": "UNIQUE-REF-001",
    "trackingNumber": "20250410X51DIQ",
    "description": "iPhone 16 pro max black edge silver back casing",
    "status": "pending",
    "statusDescription": "Package is yet to be received from Partner",
    "items": [
      { "name": "iPhone 6", "quantity": 1 },
      { "name": "iPhone 14 Pro", "quantity": 2 }
    ],
    "tracking": [
      {
        "name": "pending",
        "description": "Package is yet to be received from Partner",
        "comment": null,
        "date": "2025-04-10T11:15:00.000+00:00"
      }
    ]
  }
}

404

{
  "message": "No Region with name {destination_region} found",
  "data": null
}

Créer des Colis en Masse

POST /packages/bulk

Créer plusieurs colis

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Requête

Paramètre Type Description
packages array obligatoire.
packages.*.partner_ref string obligatoire.
packages.*.customer_name string obligatoire.
packages.*.customer_phone_1 string obligatoire.
packages.*.customer_phone_2 string optionnel.
packages.*.source_address_line_1 string obligatoire.
packages.*.source_address_line_2 string optionnel.
packages.*.destination_region string obligatoire si region_id est vide.
packages.*.destination_city string obligatoire.
packages.*.destination_address_line_1 string obligatoire.
packages.*.destination_address_line_2 string optionnel.
packages.*.destination_postal_code string optionnel.
packages.*.length decimal optionnel.
packages.*.height decimal optionnel.
packages.*.weight decimal optionnel.
packages.*.description string obligatoire.
packages.*.units number obligatoire.
packages.*.type string obligatoire . parmi parcel, box
packages.*.handling string obligatoire . parmi normal, fragile
packages.*.special_instructions string optionnel.
packages.*.latitude decimal optionnel.
packages.*.longitude decimal optionnel.
packages.*.value decimal obligatoire.
packages.*.amount_to_collect decimal optionnel. Par défaut, égal à la value du colis.
packages.*.items array obligatoire. {name, quantity}
packages.*.landmark string optionnel.
packages.*.region_id integer obligatoire si destination_region est vide.

Réponse

200

{
  "message": "Packages processed successfully",
  "data": [
    {
      "partnerRef": "UNIQUE-REF-001",
      "trackingNumber": "20250410X51DIQ",
      "description": "iPhone 16 pro max black edge silver back casing",
      "status": "pending",
      "statusDescription": "Package is yet to be received from Partner",
      "items": [
        { "name": "iPhone 6", "quantity": 1 },
        { "name": "iPhone 14 Pro", "quantity": 2 }
      ],
      "tracking": [
        {
          "name": "pending",
          "description": "Package is yet to be received from Partner",
          "comment": null,
          "date": "2025-04-10T11:15:00.000+00:00"
        }
      ]
    }
  ]
}

Créer une Expédition

POST /consignments

Créer une expédition représentant l'envoi physique de colis à ShaQ Express.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Requête

Paramètre Type Description
reference string optionnel. Clé de consignation fournie par le partenaire servant de clé d'idempotence ; si omise, une référence est générée.
packages array obligatoire. Accepte de 1 à 500 objets colis.
packages.*.partner_ref string obligatoire.
packages.*.customer_name string obligatoire.
packages.*.customer_phone_1 string obligatoire.
packages.*.customer_phone_2 string optionnel.
packages.*.source_address_line_1 string optionnel.
packages.*.source_address_line_2 string optionnel.
packages.*.destination_region string obligatoire si region_id est vide.
packages.*.destination_city string obligatoire.
packages.*.destination_address_line_1 string obligatoire.
packages.*.destination_address_line_2 string optionnel.
packages.*.destination_postal_code string optionnel.
packages.*.length decimal optionnel.
packages.*.height decimal optionnel.
packages.*.weight decimal optionnel.
packages.*.description string obligatoire.
packages.*.units number obligatoire.
packages.*.type string obligatoire . parmi parcel, box
packages.*.handling string obligatoire . parmi normal, fragile
packages.*.special_instructions string optionnel.
packages.*.latitude decimal optionnel.
packages.*.longitude decimal optionnel.
packages.*.value decimal obligatoire.
packages.*.amount_to_collect decimal optionnel. Par défaut, égal à la value du colis.
packages.*.items array obligatoire.
packages.*.landmark string optionnel.
packages.*.region_id integer obligatoire si destination_region est vide.
packages.*.include_label boolean optionnel.

Réponse

200

{
  "message": "Consignment created successfully",
  "data": {
    "id": 123,
    "reference": "PAR-20260828093000",
    "status": "pending",
    "createdAt": "2026-08-28",
    "totalPackages": 2,
    "packages": [
      {
        "partnerRef": "qwertyui1a1aaqweqqaqx",
        "trackingNumber": "C561819A",
        "customerName": "Hema Mirpuri",
        "customerPhone1": "+233244601165",
        "customerPhone2": null,
        "sourceAddressLine1": "Accra spintex basket junction",
        "sourceAddressLine2": null,
        "destinationRegion": "Greater Accra",
        "destinationCity": "Tesano",
        "destinationAddressLine1": "OPP total filling station Abeka tesano",
        "destinationAddressLine2": null,
        "destinationPostalCode": null,
        "length": 0,
        "height": 0,
        "weight": 0,
        "description": "Color Splicing Cotton Rope Storage Basket AB-026 - Beige Yellow+White",
        "units": 7,
        "type": "parcel",
        "handling": "normal",
        "specialInstructions": null,
        "status": "pending",
        "statusDescription": "Package is yet to be received by Partner",
        "latitude": null,
        "longitude": null,
        "value": "1468.00",
        "amountToCollect": "1468.00",
        "originalAmountToCollect": null,
        "paymentCollector": "shaq",
        "paymentStatus": "unpaid",
        "date": "2026-08-28 09:30",
        "trackingUrl": "https://dev.tracking-website.pages.dev/packages/C561819A",
        "items": [
          {
            "name": "14cm Alya Glass Cookie Holder - Transparent",
            "quantity": 4
          },
          {
            "name": "6 Pieces Nossa 21cm Cake Plate Set",
            "quantity": 1
          }
        ]
      },
      {
        "partnerRef": "zxcvbnm2b2bbrwerrbrby",
        "trackingNumber": "C561820B",
        "customerName": "Kwaku Ananse",
        "customerPhone1": "+233244100200",
        "customerPhone2": null,
        "sourceAddressLine1": "Accra spintex basket junction",
        "sourceAddressLine2": null,
        "destinationRegion": "Greater Accra",
        "destinationCity": "Accra",
        "destinationAddressLine1": "UPSA Hall, Room 3",
        "destinationAddressLine2": null,
        "destinationPostalCode": null,
        "length": 0,
        "height": 5,
        "weight": 1.2,
        "description": "iPhone 16 pro max black edge silver back casing",
        "units": 1,
        "type": "box",
        "handling": "normal",
        "specialInstructions": null,
        "status": "pending",
        "statusDescription": "Package is yet to be received by Partner",
        "latitude": null,
        "longitude": null,
        "value": "1468.00",
        "amountToCollect": "1468.00",
        "originalAmountToCollect": null,
        "paymentCollector": "shaq",
        "paymentStatus": "unpaid",
        "date": "2026-08-28 09:30",
        "trackingUrl": "https://dev.tracking-website.pages.dev/packages/C561820B",
        "items": [
          {
            "name": "iPhone 16 pro max",
            "quantity": 1
          }
        ]
      }
    ]
  }
}

Obtenir une Expédition Spécifique

GET /consignments/{reference}

Obtenir les détails d'une expédition

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Request successful",
  "data": {
    "id": 124,
    "reference": "SAAM-20260322053800",
    "partner": {
      "id": 16,
      "countryId": 1,
      "name": "Acme Ltd",
      "phone": "+233244601165",
      "email": "ops@acme.example",
      "identifier": "acme",
      "webhookUrl": "https://acme.example/webhooks/shaq",
      "testWebhookUrl": "https://acme.example/webhooks/shaq-test",
      "enabled": true,
      "hasLabel": true,
      "showNameOnLabel": true,
      "type": "merchant",
      "address": "Accra spintex basket junction",
      "defaultPaymentCollector": "shaq",
      "maskedSecret": "pauth_****",
      "createdAt": "2026-01-15T09:30:00.000+00:00",
      "updatedAt": "2026-08-28T09:30:00.000+00:00"
    },
    "partnerName": "Acme Ltd",
    "status": "successful",
    "type": "import",
    "author": "Acme Ltd",
    "authorName": "Acme Ltd",
    "authorType": "partner",
    "recipientId": null,
    "recipientName": null,
    "driverId": null,
    "driverName": null,
    "vehicleNumber": null,
    "receivedAt": null,
    "path": null,
    "startsAt": null,
    "endsAt": null,
    "statuses": [],
    "skippedRows": [],
    "skippedCount": 0,
    "createdAt": "2026-08-28",
    "totalPackages": 2,
    "packages": [
      {
        "partnerRef": "qwertyui1a1aaqweqqaqx",
        "trackingNumber": "C561819A",
        "customerName": "Hema Mirpuri",
        "customerPhone1": "+233244601165",
        "customerPhone2": null,
        "sourceAddressLine1": "Accra spintex basket junction",
        "sourceAddressLine2": null,
        "destinationRegion": "Greater Accra",
        "destinationCity": "Tesano",
        "destinationAddressLine1": "OPP total filling station Abeka tesano",
        "destinationAddressLine2": null,
        "destinationPostalCode": null,
        "length": 0,
        "height": 0,
        "weight": 0,
        "description": "Color Splicing Cotton Rope Storage Basket AB-026 - Beige Yellow+White",
        "units": 7,
        "type": "parcel",
        "handling": "normal",
        "specialInstructions": null,
        "status": "pending",
        "statusDescription": "Package is yet to be received by Partner",
        "latitude": null,
        "longitude": null,
        "value": "1468.00",
        "amountToCollect": "1468.00",
        "paymentCollector": "shaq",
        "paymentStatus": "unpaid",
        "date": "2026-08-28 09:30",
        "trackingUrl": "https://dev.tracking-website.pages.dev/packages/C561819A",
        "items": [
          {
            "name": "14cm Alya Glass Cookie Holder - Transparent",
            "quantity": 4
          },
          {
            "name": "6 Pieces Nossa 21cm Cake Plate Set",
            "quantity": 1
          }
        ]
      },
      {
        "partnerRef": "zxcvbnm2b2bbrwerrbrby",
        "trackingNumber": "C561820B",
        "customerName": "Kwaku Ananse",
        "customerPhone1": "+233244100200",
        "customerPhone2": null,
        "sourceAddressLine1": "Accra spintex basket junction",
        "sourceAddressLine2": null,
        "destinationRegion": "Greater Accra",
        "destinationCity": "Accra",
        "destinationAddressLine1": "UPSA Hall, Room 3",
        "destinationAddressLine2": null,
        "destinationPostalCode": null,
        "length": 0,
        "height": 5,
        "weight": 1.2,
        "description": "iPhone 16 pro max black edge silver back casing",
        "units": 1,
        "type": "box",
        "handling": "normal",
        "specialInstructions": null,
        "status": "pending",
        "statusDescription": "Package is yet to be received by Partner",
        "latitude": null,
        "longitude": null,
        "value": "1468.00",
        "amountToCollect": "1468.00",
        "paymentCollector": "shaq",
        "paymentStatus": "unpaid",
        "date": "2026-08-28 09:30",
        "trackingUrl": "https://dev.tracking-website.pages.dev/packages/C561820B",
        "items": [
          {
            "name": "iPhone 16 pro max",
            "quantity": 1
          }
        ]
      }
    ]
  }
}

Regrouper des Colis dans une Expédition

POST /consignments/group-packages

Regrouper des colis déjà créés dans une expédition en les référençant par leur partner_ref — aucun colis n'est créé, seule leur appartenance à l'expédition est définie. Seuls les colis pending qui ne font pas déjà partie d'une expédition peuvent être regroupés. La reference sert également de clé d'idempotence : réutiliser une référence existante ajoute les colis à cette expédition ; une nouvelle référence crée une nouvelle expédition.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Requête

Paramètre Type Description
reference string Obligatoire. Votre clé d'expédition / clé d'idempotence.
partner_refs array Obligatoire. De 1 à 500 valeurs partner_ref uniques de colis existants.

Réponse

200

{
  "message": "Consignment grouped successfully",
  "data": {
    "id": 1,
    "reference": "GROUP-1",
    "status": "pending",
    "createdAt": "2026-09-14",
    "totalPackages": 3,
    "packages": [
      { "partner_ref": "qwertyui1a1aaqweqqaqx", "tracking_number": "C561819A", "status": "pending" },
      { "partner_ref": "zxcvbnm2b2bbrwerrbrby", "tracking_number": "C561820B", "status": "pending" }
    ]
  }
}

422 — un ou plusieurs colis n'ont pas pu être regroupés ; rien n'est créé.

{
  "message": "Some packages could not be grouped",
  "data": {
    "not_found": ["unknownref1"],
    "not_pending": ["shippedref2"],
    "already_grouped": ["groupedref3"],
    "duplicates": ["dupref4"]
  }
}

Retirer un Colis d'une Expédition

DELETE /consignments/{reference}/packages/{partner_ref}

Retirer un seul colis d'une expédition. Seul le regroupement est supprimé — le colis lui-même n'est pas supprimé et son statut reste inchangé. Seule une expédition pending peut être modifiée.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Package removed from consignment",
  "data": {
    "id": 1,
    "reference": "GROUP-1",
    "status": "pending",
    "createdAt": "2026-09-14",
    "totalPackages": 1,
    "packages": [
      { "partner_ref": "zxcvbnm2b2bbrwerrbrby", "tracking_number": "C561820B", "status": "pending" }
    ]
  }
}

404

{ "message": "Consignment not found", "data": null }

404

{ "message": "Package not found", "data": null }

422

{ "message": "Only a pending consignment can be modified", "data": null }

422

{ "message": "Package is not part of this consignment", "data": null }

Supprimer une Expédition

DELETE /consignments/{reference}

Supprimer une expédition. Ses lignes de regroupement et d'appartenance sont supprimées ; les colis eux-mêmes ne sont pas supprimés (ils subsistent, dégroupés) et conservent leur statut. Seule une expédition pending peut être supprimée.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{ "message": "Consignment deleted", "data": null }

404

{ "message": "Consignment not found", "data": null }

422

{ "message": "Only a pending consignment can be deleted", "data": null }

Mettre à Jour un Colis

PATCH /packages/{partnerRef}

Mettre à jour un colis spécifique

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Requête

Paramètre Type Description
customer_name string optionnel.
customer_phone_1 string optionnel.
customer_phone_2 string optionnel.
source_country_iso2 string optionnel.
source_address_line_1 string optionnel.
source_address_line_2 string optionnel.
destination_region string optionnel.
destination_city string optionnel.
destination_address_line_1 string optionnel.
destination_address_line_2 string optionnel.
destination_postal_code string optionnel.
length decimal optionnel.
height decimal optionnel.
weight decimal optionnel.
description string optionnel.
units number optionnel.
type string optionnel . parmi parcel, box
handling string optionnel . parmi normal, fragile
special_instructions string optionnel.
latitude decimal optionnel.
longitude decimal optionnel.
value decimal optionnel.
amount_to_collect decimal optionnel.
items array optionnel.

Réponse

200

{
  "message": "Request successful",
  "data": {
    "partnerRef": "FGVHKJ567",
    "trackingNumber": "20250410X51DIQ",
    "customerName": "Kwaku Ananse",
    "customerPhone1": "+233244100200",
    "customerPhone2": null,
    "altPhone": null,
    "destinationRegion": "Greater Accra",
    "destinationCity": "Accra",
    "destinationAddressLine1": "UPSA Hall, Room 3",
    "destinationAddressLine2": null,
    "length": 0,
    "height": 5,
    "weight": 1.2,
    "description": "iPhone 16 pro max black edge silver back casing",
    "units": 1,
    "type": "box",
    "value": "300.00",
    "amountToCollect": "300.00",
    "paymentCollector": "shaq",
    "paymentStatus": "unpaid",
    "handling": "normal",
    "specialInstructions": null,
    "status": "not_delivered",
    "statusDescription": "Attempted delivery but couldn't complete it.",
    "latitude": null,
    "longitude": null,
    "proofPhotoUrl": "https://debtufr1vwh35.cloudfront.net/labels_test/label/8B73CE6D.png",
    "receivedAt": "Jul 15 2025",
    "isReplacement": false,
    "action": null,
    "items": [
      {
        "name": "iPhone 6",
        "quantity": 1
      },
      {
        "name": "iPhone 14 Pro",
        "quantity": 2
      }
    ],
    "rescheduledDate": null,
    "deliveredAt": null,
    "eta": "2026-04-20 - 2026-04-22",
    "maxEta": 5,
    "deliveryAttempts": 1,
    "fulfillmentStage": null,
    "fulfillmentStatus": null,
    "pickedAt": null,
    "packedAt": null,
    "cancelledAt": null,
    "trackingHistory": [
      {
        "name": "not_delivered",
        "description": "Attempted delivery but couldn't complete it.",
        "date": "2025-07-16T09:00:00.000+00:00",
        "comment": "Customer was unreachable upon arrival. Package rescheduled for 2nd delivery attempt."
      },
      {
        "name": "dispatched",
        "description": "Package is en-route to deliver.",
        "date": "2025-07-15T15:45:00.000+00:00",
        "comment": null
      }
    ],
    "callLogs": null
  }
}

Suivre un Colis

GET /tracking/{trackingNumber}

Obtenir les statuts de suivi d'un colis spécifique

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Package tracking",
  "data": {
    "partnerRef": "FGVHKJ567",
    "trackingNumber": "20250410X51DIQ",
    "description": "Kitchen cabinet",
    "status": "shipped",
    "statusDescription": "Package has been shipped by Partner.",
    "items": [
      {
        "name": "iPhone 6",
        "quantity": 1
      },
      {
        "name": "iPhone 14 Pro",
        "quantity": 2
      }
    ],
    "tracking": [
      {
        "name": "shipped",
        "description": "Package has been shipped by Partner.",
        "comment": null,
        "date": "2025-04-10T15:17:00.000+00:00"
      },
      {
        "name": "pending",
        "description": "Package is yet to be shipped by Partner.",
        "comment": null,
        "date": "2025-04-10T15:16:00.000+00:00"
      },
      {
        "name": "shipped",
        "description": "Package has been shipped by Partner.",
        "comment": null,
        "date": "2025-04-10T15:15:00.000+00:00"
      }
    ]
  }
}

Obtenir les Régions

GET /setup/regions

Obtenir toutes les régions autorisées

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Request successful",
  "data": [
    {
      "id": 16,
      "name": "Western North"
    },
    {
      "id": 15,
      "name": "Ashanti"
    }
  ]
}

Recevoir des Mises à Jour via Webhook

POST /YOUR_WEBHOOK_URL

Nous enverrons un POST à votre URL webhook chaque fois qu'un événement suivi se produit sur un colis.

Enveloppe

Chaque payload webhook partage la même enveloppe de niveau supérieur :

Champ Type Description
event string Le type d'événement. Voir Événements Webhook ci-dessous.
event_id string UUID unique par livraison. Utilisé pour l'idempotence/déduplication.
api_version string Version du payload, ex. v1
occurred_at string Horodatage UTC ISO 8601 de l'événement
data object Payload spécifique à l'événement. La forme varie selon event.

Événements Webhook

package.status_updated

Déclenché chaque fois que le statut d'un colis change.

Champ Type Description
tracking_number string Numéro de suivi ShaQ Express
partner_ref string Votre référence pour le colis
status string Le nouveau statut. Voir Statuts des Colis pour les valeurs
description string Description lisible du statut
comment string Contexte ou commentaire supplémentaire. Peut être null
meta object Données supplémentaires. Inclut proof_url quand status est delivered
{
  "event": "package.status_updated",
  "event_id": "018e2b3c-7f4a-7c2d-9e1b-4a8f3d2c6b5a",
  "api_version": "v1",
  "occurred_at": "2025-05-29T10:30:00Z",
  "data": {
    "tracking_number": "20250410X51DIQ",
    "partner_ref": "FGVHKJ567",
    "status": "delivered",
    "description": "Package was successfully delivered to customer",
    "comment": null,
    "meta": {
      "proof_url": "https://example.com/proof.jpg"
    }
  }
}

package.amount_to_collect_updated

Déclenché lorsque le montant à collecter d'un colis est révisé, toujours à la demande et avec l'approbation du Client.

Champ Type Description
tracking_number string Numéro de suivi ShaQ Express
partner_ref string Votre référence pour le colis
status string Statut du colis au moment de la révision. Voir Statuts des Colis pour les valeurs
meta.old_amount_to_collect number Ancien montant à collecter
meta.new_amount_to_collect number Nouveau montant à collecter
meta.currency string Code de devise, ex. GHS
meta.reason string Motif de la révision
{
  "event": "package.amount_to_collect_updated",
  "event_id": "039g4d5e-9h6c-9e4f-1g3d-6c0h5f4e8d7c",
  "api_version": "v1",
  "occurred_at": "2025-05-29T09:00:00Z",
  "data": {
    "tracking_number": "20250410X51DIQ",
    "partner_ref": "FGVHKJ567",
    "status": "received",
    "meta": {
      "old_amount_to_collect": 25.0,
      "new_amount_to_collect": 35.0,
      "currency": "GHS",
      "reason": "Items changed"
    }
  }
}

Réponse Attendue

Votre point de terminaison doit retourner une réponse 2xx pour accuser réception du webhook. Toute réponse non-2xx sera réessayée jusqu'à 3 fois.

{
  "message": "",
  "data": {
    "status": "OK"
  }
}

Exigences Webhook

Pour garantir une livraison fiable et éviter les délais d'expiration des webhooks, veuillez respecter les directives suivantes :

*   **Délai de Réponse :** Votre serveur doit retourner un code de statut `2xx` dans les **10 secondes** suivant la réception du payload.
*   **Traitement Asynchrone :** Accusez réception du webhook immédiatement et traitez toute opération de base de données, logique métier ou notification externe de manière asynchrone (ex. via une file d'attente en arrière-plan).
*   **Déduplication & Idempotence :** Utilisez l'`event_id` fourni dans l'enveloppe du payload pour garantir l'idempotence. Conservez un journal des IDs d'événements traités et ignorez le traitement si l'ID a déjà été vu.
*   **Attendez-vous aux Doublons :** Votre point de terminaison doit être préparé à gérer les livraisons en double en cas de nouvelles tentatives réseau ou de problèmes de connexion transitoires.

Créer un Remplacement de Colis

POST /packages/replacement

Description : Créer un ou deux colis pour remplacer un colis existant. Le champ rule détermine combien de colis sont requis et quelle action chacun doit effectuer.

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Règles

Règle Colis Requis Actions Requises
deliver 1 action = deliver
return 1 action = return
return_deliver 2 Un return, un deliver

Requête

Paramètre Type Description
rule string Obligatoire. L'un de deliver, return, return_deliver
packages array Obligatoire. 1–2 objets colis. Doit satisfaire les contraintes de la rule

Objet Colis

Chaque élément du tableau packages doit respecter la structure suivante :

Paramètre Type Description
action string Obligatoire. L'un de deliver, return. Doit correspondre à la rule
partner_ref string Obligatoire. Doit être unique
customer_name string Obligatoire
customer_phone_1 string Obligatoire. Numéro de mobile valide
customer_phone_2 string Optionnel
source_country_iso2 string Obligatoire. Code pays ISO2 valide
source_address_line_1 string Obligatoire
source_address_line_2 string Optionnel
destination_country_iso2 string Obligatoire. Code pays ISO2 valide
destination_region string Obligatoire si region_id est absent
destination_city string Obligatoire
destination_address_line_1 string Obligatoire
destination_address_line_2 string Optionnel
destination_postal_code string Optionnel
landmark string Optionnel
region_id integer Obligatoire si destination_region est absent
length decimal Optionnel
height decimal Optionnel
weight decimal Optionnel
description string Obligatoire
units number Obligatoire
type string Obligatoire. L'un de parcel, box
value decimal Obligatoire. Minimum 0
amount_to_collect decimal Optionnel. Minimum 0
handling string Obligatoire. L'un de normal, fragile
payment_collector string optionnel. parmi shaq, partner (Ce paramètre ne peut être envoyé que lorsque ShaQ Express est le collecteur de paiement. Il précise qui est responsable de la collecte du paiement auprès du client et est destiné aux cas particuliers où le partenaire gère la collecte. Si non fourni, la configuration de collecteur de paiement convenue par défaut sera utilisée.)
items array Obligatoire. Tableau de { name: string, quantity: number }. Peut être vide
special_instructions string Optionnel
latitude decimal Optionnel
longitude decimal Optionnel

Réponse

200

{
  "message": "Package replacement created successfully",
  "data": [
    {
      "partnerRef": "GH945214",
      "trackingNumber": "9F0FD9D5",
      "customerName": "Derrick Nti",
      "customerPhone1": "+233549632604",
      "customerPhone2": null,
      "altPhone": null,
      "destinationRegion": "Greater Accra",
      "destinationCity": "Kwashieman",
      "destinationAddressLine1": "23 Abiriw Street",
      "destinationAddressLine2": null,
      "length": 30,
      "height": 20,
      "weight": 5.5,
      "description": "Test package",
      "units": 1,
      "type": "box",
      "value": 20,
      "amountToCollect": 20,
      "paymentCollector": "shaq",
      "paymentStatus": "unpaid",
      "handling": "normal",
      "specialInstructions": null,
      "status": "pending",
      "statusDescription": "Package is yet to be received by Partner",
      "latitude": null,
      "longitude": null,
      "proofPhotoUrl": null,
      "receivedAt": null,
      "isReplacement": true,
      "action": "deliver",
      "items": [
        {
          "name": "Bluetooth",
          "quantity": 3
        }
      ],
      "rescheduledDate": null,
      "deliveredAt": null,
      "eta": null,
      "maxEta": null,
      "deliveryAttempts": 0,
      "fulfillmentStage": null,
      "fulfillmentStatus": null,
      "pickedAt": null,
      "packedAt": null,
      "cancelledAt": null,
      "trackingHistory": [
        {
          "name": "pending",
          "description": "Package is yet to be received by Partner",
          "date": "2026-05-04T12:16:00.000+00:00",
          "comment": null
        }
      ],
      "callLogs": null
    },
    {
      "partnerRef": "GH545728",
      "trackingNumber": "A797CA0A",
      "customerName": "Kwabena Azaglo",
      "customerPhone1": "+233549632604",
      "customerPhone2": null,
      "altPhone": null,
      "destinationRegion": "Greater Accra",
      "destinationCity": "Kwashieman",
      "destinationAddressLine1": "23 Abiriw Street",
      "destinationAddressLine2": null,
      "length": 30,
      "height": 20,
      "weight": 5.5,
      "description": "Test package",
      "units": 1,
      "type": "box",
      "value": 20,
      "amountToCollect": 20,
      "paymentCollector": "shaq",
      "paymentStatus": "unpaid",
      "handling": "normal",
      "specialInstructions": null,
      "status": "pending",
      "statusDescription": "Package is yet to be received by Partner",
      "latitude": null,
      "longitude": null,
      "proofPhotoUrl": null,
      "receivedAt": null,
      "isReplacement": true,
      "action": "return",
      "items": [
        {
          "name": "Bluetooth",
          "quantity": 3
        }
      ],
      "rescheduledDate": null,
      "deliveredAt": null,
      "eta": null,
      "maxEta": null,
      "deliveryAttempts": 0,
      "fulfillmentStage": null,
      "fulfillmentStatus": null,
      "pickedAt": null,
      "packedAt": null,
      "cancelledAt": null,
      "trackingHistory": [
        {
          "name": "pending",
          "description": "Package is yet to be received by Partner",
          "date": "2026-05-04T12:16:00.000+00:00",
          "comment": null
        }
      ],
      "callLogs": null
    }
  ]
}

Obtenir l'Étiquette d'un Colis

GET /packages/{partnerRef}/print-label

Obtenir l'étiquette d'un colis spécifique

En-têtes

Paramètre Type Description
Authorization bearer Obligatoire.

Réponse

200

{
  "message": "Request successful",
  "data": {
    "type": "base64",
    "media_type": "application/pdf",
    "data": "JVBERi0xLjQKMSAw..."
  }
}

202

{
  "message": "Label generation started. Please retry shortly.",
  "data": null
}

404

{
  "message": "Package not found",
  "data": null
}