Référence de l’API
Le contrat REST du filtrage programmatique, publié avant la mise en service pour que vous puissiez l’examiner avant d’écrire le moindre code.
L’API ARGUS retourne le même verdict que celui affiché par le site : un résultat de filtrage des sanctions en direct, un détail de l’exposition et les signaux derrière le score, sous la forme d’un objet JSON par adresse. Elle est conçue pour l’instant qui précède le mouvement des fonds — filtrez une adresse au moment du paiement, agissez selon la réponse, conservez l’objet comme trace d’audit.
Cette page est le contrat publié, non un service en fonctionnement. L’URL de base ne répond pas encore aux requêtes et aucune clé n’est délivrée. Elle est publique dès maintenant pour que les intégrateurs puissent examiner les structures avant l’existence des points de terminaison — si quelque chose ici ne conviendrait pas à votre usage, c’est exactement ce que nous voulons entendre. Demandez un accès anticipé et nous vous contacterons dès que des clés seront disponibles.
URL de base et authentification
Tous les points de terminaison sont servis en HTTPS depuis une URL de base unique et versionnés dans le chemin. Chaque requête doit porter une clé d’API sous forme de jeton Bearer ; il n’existe aucun point de terminaison non authentifié.
https://api.argus.exampleAuthorization: Bearer <your key>
Accept: application/jsonLes clés sont des secrets. Envoyez-les depuis un serveur, jamais depuis un navigateur — une clé livrée à un client est publique dès le chargement de la page.
Filtrer une adresse
Filtre une adresse et retourne un verdict complet. Le paramètre de chemin address est la seule entrée : une adresse EVM (0x plus 40 caractères hexadécimaux) ou une adresse TRON (T plus 33 caractères base58). Le réseau est déduit de la forme — une adresse EVM est la même chaîne sur toutes les chaînes EVM, la filtrer une fois les couvre donc toutes.
curl https://api.argus.example/v1/screen/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t \
-H "Authorization: Bearer $ARGUS_API_KEY"const address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
const res = await fetch(`https://api.argus.example/v1/screen/${address}`, {
headers: { Authorization: `Bearer ${process.env.ARGUS_API_KEY}` },
});
if (!res.ok) throw new Error(`Screening failed: ${res.status}`);
const verdict: ScreenResult = await res.json();
if (verdict.sanctions.hit !== null) {
// Designated. Decisive on its own — decline before funds move.
}type Band = "clear" | "caution" | "high" | "severe";
interface SanctionsHit {
name: string; // the designated person or entity
uid: number | null; // OFAC's SDN entry id
type: string; // "Individual" | "Entity"
asset: string; // ticker OFAC recorded the address under
programs: string[]; // e.g. ["DPRK3", "CYBER2"]
}
interface ScreenResult {
address: string;
network: "evm" | "tron";
score: number | null; // 0–100; null when no score is justified
band: Band | null; // clear <30 · caution <55 · high <75 · severe
sanctions: {
hit: SanctionsHit | null; // null = screened and not found,
// never "not screened"
publishDate: string; // OFAC's own date, MM/DD/YYYY
addressCount: number; // addresses in the screened snapshot
sourceUrl: string;
};
exposure: {
label: string; // source category, e.g. "Mixer"
share: number; // percentage of inbound value
band: Band | "unknown";
}[];
signals: {
title: string;
detail: string;
band: Band | "unknown";
}[];
// true while exposure and signals carry sample figures pending the
// graph indexer; the sanctions block is live regardless
exposureIsIllustrative: boolean;
}{
"address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"network": "tron",
"score": null,
"band": null,
"sanctions": {
"hit": null,
"publishDate": "08/20/2026",
"addressCount": 961,
"sourceUrl": "https://ofac.treasury.gov/sanctions-list-service"
},
"exposure": [
{ "label": "Major exchange", "share": 61.4, "band": "clear" },
{ "label": "Unattributed", "share": 12.6, "band": "unknown" }
],
"signals": [
{
"title": "Majority of inbound value from a regulated venue",
"detail": "61.4% · withdrawal pattern consistent with retail",
"band": "clear"
}
],
"exposureIsIllustrative": true
}Pourquoi score peut valoir null. Un score composite exige les niveaux exposition, comportement et attribution, et ceux-ci ne sont pas encore actifs. Fabriquer un chiffre malgré tout produirait la seule chose qu’un outil de filtrage ne doit jamais faire : se contredire — "hit": null dans le bloc sanctions à côté d’un "score": 94 inventé se lit comme un générateur de nombres aléatoires, et coûte plus de confiance qu’un champ vide n’en coûtera jamais. Le score n’est donc présent que lorsqu’un niveau actif le justifie : une désignation OFAC directe retourne 100 et "severe", et une contrepartie désignée trouvée à un saut retourne un score élevé avec le constat dans signals. Sinon, score et band valent tous deux null, et votre intégration doit traiter cela comme « non noté », non comme « risque faible ».
La même honnêteté s’applique à sanctions.hit: null — cela signifie que l’adresse a été filtrée au regard de l’instantané et n’y figure pas, et le champ publishDate qui l’accompagne indique de quel instantané il s’agit. Une désignation postérieure à cette date n’apparaîtrait pas. Tant que exposureIsIllustrative vaut true, les tableaux d’exposition et de signaux contiennent des chiffres d’exemple et ne doivent pas guider une décision.
Filtrage par lot
Filtre jusqu’à 100 adresses en une seule requête. Les réseaux peuvent être mélangés. Les résultats reviennent dans l’ordre d’entrée, et une entrée qui échoue à la validation est retournée sous forme d’objet d’erreur à sa place, sans faire échouer tout le lot — une faute de frappe ne doit pas annuler les 99 verdicts qui l’accompagnent.
curl -X POST https://api.argus.example/v1/screen/batch \
-H "Authorization: Bearer $ARGUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"addresses": [
"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"0xdAC17F958D2ee523a2206206994597C13D831ec7"
]
}'{
"results": [
{ "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "…": "…" },
{
"error": {
"code": "invalid_address",
"message": "TRON address failed base58check."
}
}
]
}Chaque adresse d’un lot est décomptée comme un appel. Les lots de plus de 100 entrées sont rejetés avec 400 invalid_request plutôt que tronqués silencieusement.
Erreurs
Les erreurs sont en JSON avec un code stable lisible par machine ; le message s’adresse aux humains et peut changer.
{
"error": {
"code": "invalid_address",
"message": "TRON address failed base58check — likely a typo."
}
}L’adresse échoue à la validation. En EVM, elle doit correspondre à 0x plus 40 caractères hexadécimaux. En TRON, elle doit être en base58 et passer l’intégralité de la somme de contrôle base58check — le champ de saisie du site ne valide que la forme, si bien qu’une faute de frappe TRON peut sembler plausible jusqu’à la somme de contrôle ; l’API la rejette ici plutôt que de filtrer la mauvaise adresse.
Le corps n’est pas un JSON valide, addresses est vide, ou un lot dépasse 100 entrées.
La clé d’API est absente, mal formée ou révoquée.
Route ou version inexistante. Jamais utilisé pour une adresse valide sans historique — une adresse qui n’a jamais transigé donne un résultat 200 normal, pas une erreur.
Limite par clé dépassée. L’en-tête Retry-After indique quand réessayer.
Une source de données de chaîne est indisponible ou a expiré. Le filtrage des sanctions s’exécute sur un instantané local, il se dégrade donc en dernier. Réessai sûr avec backoff ; les lectures de filtrage sont idempotentes.
Limites de débit et décompte
L’accès à l’API fait partie de l’offre API présentée sur la page des tarifs : 0,04 $ par appel, tarif dégressif à partir de 50 000 appels, filtrage par lot illimité. Les limites ci-dessous font partie de cette spécification — publiées pour examen comme tout le reste ici, et confirmées au lancement.
Dépasser une limite retourne 429 rate_limited avec un en-tête Retry-After. Les limites s’appliquent par clé, non par IP.
Webhooks
Filtrer une adresse une fois ne renseigne que sur cet instant. La liste évolue ensuite : l’OFAC publie de nouvelles désignations, et une adresse sans correspondance le mois dernier peut être désignée aujourd’hui. Les webhooks comblent cet écart — lorsqu’une adresse déjà filtrée par votre clé apparaît dans une publication SDN plus récente, ARGUS envoie un événement sanctions.designation au point de terminaison que vous avez configuré.
{
"id": "evt_9f2c81d4",
"type": "sanctions.designation",
"createdAt": "2026-09-02T14:11:08Z",
"data": {
"address": "T111111111111111111111111111111111",
"network": "tron",
"firstScreenedAt": "2026-08-23T09:30:00Z",
"hit": {
"name": "EXAMPLE DESIGNATED ENTITY",
"uid": 99999,
"type": "Entity",
"asset": "TRX",
"programs": ["CYBER2"]
},
"listPublishDate": "09/01/2026"
}
}Les livraisons sont signées via un en-tête de signature HMAC-SHA256 afin que vous puissiez vérifier que la charge utile vient bien de nous, et sont réessayées avec backoff pendant 24 heures jusqu’à ce que votre point de terminaison retourne un 2xx. L’adresse et l’entité ci-dessus sont fictives — l’adresse ne peut pas passer le base58check et l’entité n’existe pas.
Accès anticipé
Aucune clé n’est encore délivrée. Si vous souhaitez développer sur cette API — ou si vous y voyez déjà un problème — dites-le via la page contact, rubrique « API et partenariats ». Les intégrateurs qui examinent la spécification dès maintenant recevront les premières clés, et les changements faits avant le lancement ne coûtent rien.