Développeurs
API de contrôle douanier
Le même contrôle que sur ce site, appelé depuis votre logiciel. Vous envoyez un dossier en JSON, vous recevez un score sur 100, les points bloquants, les alertes et les actions recommandées — avec des codes d'anomalies stables et des messages traduits dans les 24 langues officielles de l'Union européenne.
API serveur-à-serveur. Une clé est un secret. Les appels depuis un navigateur ne sont pas pris en charge et aucun en-tête CORS n'est envoyé sur les routes authentifiées : une clé qui arrive dans un navigateur est une clé divulguée.
Vue d'ensemble
L'API expose le moteur de contrôle du validateur : quatorze règles transverses, cinq règles TARIC, quatre règles de complétude documentaire et les validateurs propres à chaque système déclaratif. Elle ne télétransmet rien : elle vérifie le format et la cohérence de votre dossier, l'existence des codes dans la nomenclature et, pour une importation dans l'Union, les mesures TARIC applicables à l'origine (antidumping, contrôles, préférences, taux de droit), avant que vous ne prépariez la déclaration.
Toutes les routes sont préfixées par leur version. Les routes de découverte et la spécification sont publiques : un intégrateur, ou un agent, peut lire le schéma avant même d'avoir une clé.
| Route | Rôle | Authentification |
|---|---|---|
| POST/v1/checks | Contrôle un dossier et renvoie le rapport complet | Clé requise |
| POST/v1/checks/batch | Contrôle jusqu'à 25 dossiers en un appel | Clé requise |
| GET/v1/me | Renvoie la clé courante et son quota, sans le consommer | Clé requise |
| GET/v1/declaration-types | Liste les types de déclaration reconnus | Publique |
| GET/v1/declaration-types/{type} | Décrit les champs attendus pour un type | Publique |
| GET/v1/openapi.json | Spécification OpenAPI 3.1 de l'API | Publique |
Authentification
L'API s'authentifie par jeton porteur. Le jeton n'est affiché qu'une fois, au moment de la création : seule son empreinte est conservée, une clé perdue se remplace mais ne se récupère pas.
Vous pouvez détenir trois clés actives simultanément, ce qui permet de faire tourner une clé sans interrompre votre intégration : créez la nouvelle, déployez-la, puis révoquez l'ancienne.
- 01Créez une clé depuis votre compte, dans l'espace « Clés API ».
- 02Envoyez-la dans l'en-tête Authorization de chaque requête.
- 03Révoquez-la si elle fuite : la coupure est immédiate et le contenu des dossiers soumis avec cette clé est purgé dans la foulée.
Authorization: Bearer cc_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxPremier contrôle
Un dossier se compose d'un type, d'un en-tête et de lignes de marchandises. Toutes les valeurs sont des chaînes de caractères : le moteur s'occupe de les interpréter. Les noms des champs se découvrent à l'exécution, type par type.
La réponse arrive immédiatement, il n'y a rien à interroger ensuite.
curl https://www.customs-check.com/api/v1/checks \
-H "Authorization: Bearer $CUSTOM_CHECK_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "import-export",
"reference": "PO-2026-114",
"header": {
"flow": "IM",
"shipmentCountry": "CN",
"destinationCountry": "FR",
"incoterm": "FOB",
"companyName": "Acme SAS",
"companyCountry": "FR",
"eori": "FR12345678900012",
"transportMode": "sea",
"currency": "USD",
"invoiceTotal": "12500"
},
"items": [
{
"description": "Leather sport shoes",
"hsCode": "6403990000",
"quantity": "500",
"value": "12500",
"origin": "VN",
"grossMass": "850",
"netMass": "800"
}
],
"documents": { "commercialInvoice": "available", "packingList": "missing" }
}'Lire la réponse
Chaque anomalie porte à la fois une identité machine et une phrase lisible. Construisez votre logique sur l'identité machine : elle ne change pas sans changement de version.
- severity · code · path · rule
- Contrat stableStables. De nouveaux codes peuvent apparaître, les codes existants ne sont pas renommés sans changement de version.
- field · message · text
- AffichageTraduits pour l'affichage. Ils peuvent être reformulés à tout moment : ne les comparez jamais dans votre code.
- engine.version
- Change dès qu'une évolution des règles modifie le score d'un dossier inchangé. Archivez-la avec vos rapports.
Le champ « path » suit la forme de votre requête, ce qui permet de rattacher une anomalie directement au champ concerné dans votre propre interface.
header.<champ> · items.<n>.<champ> · documents.<category> · global
{
"id": "4c749e25-3408-48f9-b3ca-b18a7ad84681",
"createdAt": "2026-09-16T12:46:13.186Z",
"type": "import-export",
"locale": "en",
"reference": "PO-2026-114",
"score": 90,
"level": "good",
"counts": { "errors": 0, "warnings": 2, "infos": 1 },
"documents": { "commercialInvoice": "available", "packingList": "missing" },
"issues": [
{
"severity": "warning",
"code": "docPackingListMissing",
"path": "documents.packingList",
"rule": "DOC-002",
"params": null,
"field": "Packing list",
"message": "Packing list not provided",
"text": "Packing list not provided"
},
{
"severity": "warning",
"code": "docTransportMissing",
"path": "documents.transportDocument",
"rule": "DOC-003",
"params": null,
"field": "Transport document (B/L, AWB, CMR)",
"message": "Transport document not provided",
"text": "Transport document not provided"
}
],
"actions": [
{ "severity": "warning", "code": "docPackingListMissing",
"path": "documents.packingList", "text": "Add: Packing list" }
],
"tips": [
{
"severity": "info",
"code": "taricControlsPossible",
"path": "items.0.hsCode",
"rule": "RULE-017",
"params": { "measures": "Import control - CITES ; Import control on seal products" },
"field": "Product 1 — HS / commodity code (if known)",
"message": "Possible import controls depending on the goods (Import control - CITES ; Import control on seal products): check whether they apply.",
"text": "Product 1 — HS / commodity code (if known): Possible import controls depending on the goods (Import control - CITES ; Import control on seal products): check whether they apply."
}
],
"engine": { "version": "1.6.0", "rules": 25, "taric": "2026-10-01" }
}Découvrir les champs
Les types de déclaration et leurs champs sont publics, aucune clé n'est nécessaire. C'est la route à utiliser pour construire un formulaire, alimenter un mappage depuis votre ERP, ou donner à un agent le schéma qu'il doit remplir.
Les noms renvoyés ici sont exactement les clés à employer dans l'en-tête et dans chaque ligne de marchandise. Les listes d'options sont résolues et traduites ; ajoutez le paramètre pour les omettre si la réponse vous paraît trop lourde.
# The 8 declaration types
curl "https://www.customs-check.com/api/v1/declaration-types?locale=en"
# The fields of one type
curl "https://www.customs-check.com/api/v1/declaration-types/h7?locale=en"
# Same, without the resolved option lists
curl "https://www.customs-check.com/api/v1/declaration-types/h7?options=false"Traitement par lot
Jusqu'à 25 dossiers par appel. La réponse est toujours un succès dès lors que le lot est accepté, et chaque entrée porte son propre statut : un dossier mal formé ne fait jamais échouer les autres.
Si le quota restant ne couvre pas toutes les entrées valides, le lot entier est refusé plutôt que traité partiellement — vous n'avez jamais à deviner où le traitement s'est arrêté.
curl https://www.customs-check.com/api/v1/checks/batch \
-H "Authorization: Bearer $CUSTOM_CHECK_KEY" \
-H "Content-Type: application/json" \
-d '{ "checks": [ { "type": "h7", "header": {}, "items": [] } ] }'Agents et outils
En plus des routes REST, le même moteur et les mêmes données sont accessibles depuis un assistant d'IA, par un serveur MCP (Model Context Protocol), et depuis un client d'API, par une collection Postman toute prête. Les deux utilisent la clé d'API et le quota quotidien décrits plus haut.
Serveur MCP
Le serveur MCP permet à un assistant de chercher un code douanier, de lire le droit d'importation européen d'un code, de contrôler un numéro EORI, de TVA ou d'OEA dans les registres officiels et de contrôler un brouillon de déclaration, sans que vous écriviez une ligne de code de liaison. Il répond sur POST /api/mcp, en JSON.
Il est sans état et parle les deux générations du protocole : la révision 2026-07-28, où chaque requête porte sa version, et les révisions antérieures qui s'ouvrent par un appel initialize. La connexion, la découverte et la liste des outils sont gratuites ; chaque appel d'outil consomme une unité du quota quotidien de la clé.
L'authentification est le même jeton porteur que l'API REST. Un client qui n'accepte que la connexion OAuth, comme les connecteurs web de claude.ai, ne peut pas encore se connecter : utilisez un client qui permet de poser un en-tête.
POST https://www.customs-check.com/api/mcp
claude mcp add --transport http customs-check https://www.customs-check.com/api/mcp \
--header "Authorization: Bearer $CUSTOM_CHECK_KEY"| check_declaration | Contrôle un brouillon de déclaration : score sur 100, niveau et chaque anomalie avec son champ et l'action à mener. Ne conserve pas le contenu du dossier sauf demande. |
| list_declaration_types | Les systèmes déclaratifs pris en charge, avec autorité, région et documents attendus. |
| describe_declaration_type | Les champs d'en-tête et de ligne d'un type, pour construire l'entrée de check_declaration. |
| search_hs_codes | Codes candidats de la nomenclature combinée à partir d'une description de produit, dans les 24 langues de l'UE. |
| describe_hs_code | Dit si un code de 4 à 10 chiffres existe dans la nomenclature en vigueur, avec son chemin officiel et son libellé. |
| lookup_import_duty | Droit d'importation européen d'un code d'après les données TARIC de la Commission : droit pays tiers, préférences d'une origine, contingents, antidumping et contrôles. |
| search_chemical | Une substance chimique par numéro CAS, numéro CUS ou nom, dans l'inventaire ECICS de la Commission : le code de la nomenclature combinée donné pour chaque entrée, à vérifier. |
| get_quota_balance | Solde restant d'un contingent tarifaire de l'UE dans la base QUOTA de la Commission, à partir de son numéro d'ordre ou d'un code et d'une origine : solde, état (ouvert, critique, bloqué, épuisé), période et heure de la lecture. |
| validate_eori | Format d'un numéro EORI et son statut dans le registre officiel (Commission européenne, HMRC). |
| validate_vat | Format d'un numéro de TVA de l'UE et sa validité dans VIES, avec la raison sociale quand elle est publiée. |
| check_rex | Format d'un numéro REX d'exportateur enregistré et son état dans la base REX de la Commission (valide, révoqué ou inconnu), avec ses dates. |
| screen_sanctions | Une entreprise, une personne ou un navire face aux listes de sanctions de l'UE, de l'ONU, du Royaume-Uni et des États-Unis, mises à jour chaque jour : chaque correspondance avec son score, forte ou partielle. |
| search_aeo | Recherche dans la base des opérateurs économiques agréés de la Commission, par raison sociale. |
- Les codes douaniers sont des suggestions tirées du libellé de la nomenclature. Seul le déclarant, ou une décision de renseignement tarifaire contraignant de la douane, peut confirmer un classement.
- Les droits sont indicatifs : conditions, exclusions de pays et contingents épuisés ne sont pas évalués. Chaque réponse porte la date de référence de l'extraction TARIC, renouvelée chaque mois.
- Un registre qui ne répond pas est signalé comme indisponible, jamais comme un numéro invalide. Rien n'est jamais envoyé à la douane.
Collection Postman
La collection est générée à partir de la spécification OpenAPI, donc toujours conforme : une requête par route, groupées par étiquette, avec un squelette de corps pour chaque POST. Importez-la dans Postman, renseignez la variable apiKey (gardée secrète) et les requêtes sont prêtes à partir.
Télécharger la collectionQuota
Chaque clé dispose de 500 contrôles par jour calendaire UTC. L'état courant accompagne chaque réponse authentifiée, vous n'avez donc jamais besoin d'un appel supplémentaire pour le connaître.
Les appels refusés sont comptés : un client qui boucle sur des requêtes invalides se limite donc lui-même. Le quota est fixé par clé — écrivez-nous s'il vous faut davantage.
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 437
X-RateLimit-Reset: 1789603200
X-RateLimit-Policy: 500;w=86400Erreurs
Les messages d'erreur sont en anglais uniquement : ce sont des messages de protocole, destinés à des développeurs. Seul le contenu métier est traduit.
Chaque réponse porte un identifiant de requête, repris dans le corps. Citez-le lorsque vous nous contactez, il nous mène directement à l'appel concerné.
{
"error": {
"code": "invalid_request",
"message": "The request body failed validation.",
"details": [
{ "path": "items.0.quantity", "message": "expected a string" }
],
"requestId": "2bbb0946-6178-4b54-921c-b28f794c44bd"
}
}| Statut | code | Signification |
|---|---|---|
| 400 | invalid_json | Le corps n'est pas du JSON valide. |
| 422 | invalid_request | Le JSON est valide mais son contenu ne l'est pas. Le détail indique le champ fautif. |
| 401 | missing_credentials | En-tête Authorization absent ou mal formé. |
| 401 | invalid_key | Clé inconnue. |
| 401 | key_revoked | Clé révoquée. |
| 403 | account_suspended | Le compte propriétaire de la clé est suspendu. |
| 415 | unsupported_media_type | Le type de contenu n'est pas du JSON. |
| 413 | payload_too_large | Corps de requête trop volumineux. |
| 429 | rate_limit_exceeded | Quota journalier atteint. Voir l'en-tête Retry-After. |
| 500 | internal_error | Erreur de notre côté. Réessayez, puis signalez-la-nous avec l'identifiant de requête. |
Données et conservation
Les dossiers transmis par l'API sont des données de vos clients : nous en gardons le moins possible, et vous disposez d'un interrupteur pour n'en garder aucune.
- Envoyez « store » à false pour que rien du contenu ne soit écrit : seuls le score et les codes d'anomalies sont conservés.
- À défaut, le contenu des dossiers est purgé au bout de 30 jours.
- Révoquer une clé purge immédiatement le contenu des dossiers qu'elle a soumis.
- Les traitements ont lieu à Francfort et la base est hébergée dans l'Union européenne.
- Aucun fichier n'est déposé par l'API : vous déclarez seulement quels documents vous détenez.
200 items · 256 KB · 25 / batch · reference ≤ 64
Ce que cette API n'est pas
Le contrôle est une aide à la préparation. Il ne constitue pas une validation par l'administration des douanes, il ne dépose rien, et il ne remplace pas les obligations réglementaires applicables à votre opération.
Les codes douaniers sont vérifiés sur leur format, leur existence dans la nomenclature et, à l'importation dans l'Union, les mesures TARIC de leur origine, jamais sur le classement de la marchandise : un code existant reste un code à vérifier. Les mesures TARIC sont indicatives (extraction mensuelle de la Commission européenne) : exclusions de pays, contingents épuisés et droits conditionnels ne sont pas évalués.