Documentation API
Affreta expose une API REST et des webhooks signés pour intégrer vos appels d'offres transport à votre ERP, WMS ou vos scripts. Cette documentation est publique. Pour appeler l'API, générez une clé dans l'application → Intégrations API.
Base & authentification
URL de base : https://app.affreta.com
Chaque requête s'authentifie par une clé d'organisation, dans l'en-tête Authorization :
Authorization: Bearer aff_live_xxxxxxxxxxxxxxxxxxxxxxxx
La clé se génère dans l'app (Intégrations API), est affichée une seule fois, stockée hachée, et révocable à tout moment. Une clé peut porter le scope write (nécessaire pour créer). Sans clé valide, l'API répond 401.
Endpoints
GET /api/v1/requests
Liste les demandes de l'organisation, les plus récentes d'abord. Paramètres : limit (défaut 50, max 200), statut (filtre optionnel).
curl -H "Authorization: Bearer aff_live_xxx" \ "https://app.affreta.com/api/v1/requests?statut=cloture&limit=50"
Réponse : { "data": [ … ] }. Chaque demande contient notamment : id, reference, statut, type_transport, date_enlevement, date_livraison, adresse_enlevement, adresse_livraison, partenaire, nature_marchandise, nb_colis, poids_kg, volume_m3, offers_count, replies_count, best_offer ({ transporteur, price_eur, delai_jours }) et le détail offers[].
POST /api/v1/requests
Crée une demande (en brouillon) depuis un système tiers. Nécessite le scope write.
| Champ | Type | Requis |
|---|---|---|
date_enlevement | string (YYYY-MM-DD) | oui |
type_transport | depart | reception | non |
date_livraison | string (YYYY-MM-DD) | non |
reference, partenaire | string | non |
adresse_enlevement, adresse_livraison | string | non |
nb_colis, poids_kg, volume_m3 | number | non |
nature_marchandise, notes | string | non |
curl -X POST "https://app.affreta.com/api/v1/requests" \ -H "Authorization: Bearer aff_live_xxx" \ -H "Content-Type: application/json" \ -d '{ "date_enlevement": "2026-10-02", "adresse_enlevement": "Lyon 69007", "adresse_livraison": "Nantes 44000", "nb_colis": 12, "poids_kg": 4200, "reference": "CMD-10482" }'
Réponse : { "id": "…", "statut": "brouillon" } (HTTP 201).
GET /api/v1/carriers
Liste les transporteurs (panel) de l'organisation.
curl -H "Authorization: Bearer aff_live_xxx" \ "https://app.affreta.com/api/v1/carriers"
Webhooks
Dans Intégrations API, renseignez une URL et un secret. Affreta envoie alors un POST JSON à chaque événement :
| Événement | Déclencheur |
|---|---|
offer.received | un transporteur a déposé un prix |
offer.declined | un transporteur a décliné |
ping | test manuel depuis l'app |
Corps :
{
"event": "offer.received",
"created_at": "2026-09-18T09:12:40.000Z",
"data": { "request_id": "…", "transporteur": "…", "price_eur": 512, "delai_jours": 2 }
}
Vérifier la signature
Chaque requête porte les en-têtes x-affreta-event et x-affreta-signature. La signature est un HMAC-SHA256 du corps brut avec votre secret, préfixé de sha256=. Vérifiez-la avant de traiter l'événement :
// Node.js
import crypto from "crypto";
const sig = "sha256=" + crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
if (sig !== req.headers["x-affreta-signature"]) return res.status(401).end();
Erreurs
Les erreurs renvoient un JSON { "error": "…" } avec un statut HTTP : 400 (requête invalide), 401 (clé absente/invalide), 403 (scope insuffisant), 500 (erreur serveur).
Intégration ERP / WMS
Il n'existe pas de connecteur ERP « clé en main » : l'intégration se fait via cette API REST et ces webhooks, câblés à votre système par votre intégrateur (directement, ou via un middleware type Make/n8n). Des connecteurs dédiés peuvent être développés au cas par cas — écrivez-nous à hello@valkode.fr.