Documentation API

AgentGate est une couche d'autorisation qui s'intercale entre vos agents IA et tout rail de paiement (carte, virement bancaire, crypto). L'agent demande l'autorisation en premier — AgentGate évalue les politiques, calcule un score de risque, et route optionnellement vers un validateur humain. Ce n'est qu'après une décision explicite APPROVED que l'agent contacte son prestataire de paiement.

Nous ne touchons jamais à votre argent. Nous décidons si votre agent en a le droit.

Agent → POST /payment-intents → AgentGate
↓ évaluation des politiques + score de risque
← APPROVED / REJECTED / PENDING_HUMAN_REVIEW
Si APPROVED :
L'agent appelle son prestataire de paiement (Stripe, API bancaire, portefeuille crypto…)
L'agent confirme : POST /payment-intents/:id/execute
Si PENDING_HUMAN_REVIEW :
↓ un humain décide dans le tableau de bord
L'agent est notifié → puis procède à l'exécution

URL de base

https://agentgate.eu/api/v1

Authentification

Toutes les requêtes nécessitent un token Bearer dans le header Authorization. Chaque agent possède sa propre clé, générée depuis le tableau de bord et affichée une seule fois. Les clés peuvent être renouvelées à tout moment depuis Paramètres → Agents → Renouveler la clé.

Authorization: Bearer ag_live_a4f2c1e9d8b7a3...

1. Soumettre une intention de paiement

POST /api/v1/payment-intents

L'unique appel que votre agent effectue avant de toucher à de l'argent. Retourne une décision en un seul aller-retour si une politique correspond ; sinon met la requête en attente de validation humaine.

Headers requis

Corps de la requête

{
  "amount_minor":  24900,            // entier, plus petite unité monétaire (ex. centimes)
  "currency":      "EUR",            // ISO-4217, 3 lettres majuscules
  "beneficiary": {
    "name":               "AWS",
    "account_identifier": "DE12500105170648489890",  // IBAN, adresse de portefeuille, id de compte…
    "category":           "infrastructure"           // optionnel
  },
  "category":   "infrastructure",    // comparé aux politiques CATEGORY_BLOCKLIST
  "memo":       "Facture mensuelle", // optionnel — améliore le contexte de validation humaine
  "metadata":   { "invoice_id": "INV-042" },  // optionnel, stocké tel quel

  // ── Options de notification (choisir une ou aucune) ───────────────────────────
  "callback_url": "https://votre-agent.example/hooks/agentgate"
  //  AgentGate enverra un POST à cette URL dès qu'un humain décide.
  //  Signé avec HMAC-SHA256 (voir "Recevoir les notifications" ci-dessous).
}

Exemples

curl -X POST https://agentgate.eu/api/v1/payment-intents \
  -H "Authorization: Bearer $AGENTGATE_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_minor": 24900,
    "currency": "EUR",
    "beneficiary": {
      "name": "AWS",
      "account_identifier": "DE12500105170648489890"
    },
    "category": "infrastructure",
    "memo": "Facture mensuelle"
  }'

Réponse (201 Created)

{
  "id":              "8a4f3b1e-...",
  "status":          "APPROVED" | "REJECTED" | "PENDING_HUMAN_REVIEW",
  "decision":        "APPROVED" | "REJECTED" | "REQUIRES_HUMAN_APPROVAL",
  "decisionReason":  "amount_lt_500000_EUR",
  "matchedPolicyId": "p1_...",
  "requiresApproval": false,
  "expiresAt":       "2026-05-04T12:15:00.000Z"  // défini si APPROVED ; null sinon
}

2. Traiter la décision

DécisionStatutAction de l'agent
APPROVEDAPPROVEDAppelez votre prestataire de paiement, puis confirmez avec POST /payment-intents/:id/execute dans les 15 minutes.
REJECTEDREJECTEDDéfinitif. Arrêtez le paiement — ne pas réessayer.
REQUIRES_HUMAN_APPROVALPENDING_HUMAN_REVIEWAttendez qu'un humain décide. Choisissez l'une des trois stratégies de notification ci-dessous.

Attendre la validation humaine

Lorsque la décision est REQUIRES_HUMAN_APPROVAL, un humain doit approuver ou rejeter l'intention dans le tableau de bord avant que l'agent puisse continuer. Il existe trois façons de savoir quand cela se produit.

A

Polling — le plus simple, aucune infrastructure requise

Interrogez GET /api/v1/payment-intents/:id toutes les quelques secondes jusqu'à ce que status quitte PENDING_HUMAN_REVIEW. Fonctionne partout, sans URL publique.

import time, requests

def wait_for_decision(intent_id: str, poll_interval: int = 5, timeout: int = 600):
    deadline = time.time() + timeout
    while time.time() < deadline:
        resp = requests.get(
            f"https://agentgate.eu/api/v1/payment-intents/{intent_id}",
            headers={"Authorization": f"Bearer {os.environ['AGENTGATE_KEY']}"},
            timeout=10,
        ).json()
        status = resp["status"]
        if status == "APPROVED":
            return "approved"
        if status in ("REJECTED", "CANCELLED"):
            return status.lower()
        time.sleep(poll_interval)
    raise TimeoutError("still pending")
B

Callback URL — idéal pour les agents serverless et asynchrones

Passez un callback_url lors de la soumission de l'intention. AgentGate enverra un POST à cette URL dès qu'un humain décide — signé avec HMAC-SHA256 pour vérifier l'authenticité. Idéal pour les fonctions Lambda, Cloud Run, ou tout agent qui ne peut pas maintenir une connexion ouverte.

curl -X POST https://agentgate.eu/api/v1/payment-intents \
  -H "Authorization: Bearer $AGENTGATE_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_minor": 50000,
    "currency": "EUR",
    "beneficiary": { "name": "Stripe", "account_identifier": "acct_1A2B3C" },
    "category": "saas",
    "callback_url": "https://votre-agent.example/hooks/agentgate"
  }'
Payload du callback : { event, payment_intent_id, status, decision_reason, resolved_at, comment?, reject_reason? }
C

SSE /wait — idéal pour les agents synchrones

Ouvrez une connexion GET longue durée vers /api/v1/payment-intents/:id/wait. Le serveur la maintient ouverte, vérifie les changements de statut toutes les 2 secondes, et envoie un Server-Sent Event dès que l'humain décide. Aucune URL publique requise — l'agent bloque simplement sur le flux. Délai max : 10 minutes (configurable via ?timeout_ms=).

# Bloque jusqu'à la décision humaine (ou 10 min de délai)
curl -N https://agentgate.eu/api/v1/payment-intents/$INTENT_ID/wait \
  -H "Authorization: Bearer $AGENTGATE_KEY"

# Sortie :
# : heartbeat
# : heartbeat
# event: intent.approved
# data: {"id":"...","status":"APPROVED","decision_reason":"...","expires_at":"..."}
Événements : intent.approved · intent.rejected · intent.expired · timeout. Heartbeats toutes les 15s pour maintenir les proxies actifs.

Fenêtre d'autorisation (15 minutes)

Chaque intention APPROVED porte un horodatage expires_at fixé 15 minutes après l'approbation. Si l'agent appelle POST /payment-intents/:id/execute après cette fenêtre, l'endpoint retourne 410 Gone avec le code intent_expired et l'intention est automatiquement annulée.

// 410 Gone
{
  "error": {
    "code":       "intent_expired",
    "message":    "Authorization expired at 2026-05-04T12:15:00.000Z",
    "expiredAt":  "2026-05-04T12:15:00.000Z"
  }
}

Si vous avez besoin de plus de temps, annulez l'intention originale et re-soumettez avec une nouvelle clé d'idempotence. La fenêtre de 15 minutes est intentionnelle — les autorisations périmées constituent un vecteur d'attaque courant.

3. Confirmer l'exécution

POST /api/v1/payment-intents/:id/execute

Appelez ceci après que votre prestataire de paiement a traité la transaction. Cela clôture la piste d'audit et marque l'intention comme EXECUTED. Valide uniquement si le statut est APPROVED et que expires_at n'est pas dépassé.

curl -X POST https://agentgate.eu/api/v1/payment-intents/$INTENT_ID/execute \
  -H "Authorization: Bearer $AGENTGATE_KEY"

Autres endpoints

Webhooks au niveau de l'organisation

Enregistrez des endpoints dans les Paramètres pour recevoir tous les événements de votre organisation (utile pour les pipelines de logs, les alertes Slack, etc.). Chaque livraison est signée HMAC-SHA256.

Types d'événements

Vérification de signature

import { verifyWebhookSignature } from "@agentgate/node";

const rawBody = await request.text();
const signature = request.headers.get("x-agentgate-signature")!;
const event = verifyWebhookSignature(rawBody, signature, process.env.WEBHOOK_SECRET!);

if (event.type === "intent.approved") {
  // journaliser, alerter, déclencher un workflow en aval…
}

Erreurs

StatutCodeSignification
400validation_errorLe corps ne correspond pas au schéma.
400missing_idempotency_keyHeader absent ou malformé.
401agent_auth_failedToken Bearer invalide ou inactif.
404not_foundIntention introuvable ou n'appartenant pas à votre organisation.
409invalid_stateAction non autorisée dans le statut actuel.
410intent_expiredFenêtre d'autorisation (15 min) expirée — intention annulée.
500internal_errorErreur inattendue côté serveur.
// Toutes les erreurs suivent ce format :
{
  "error": {
    "code":    "intent_expired",
    "message": "Authorization expired at 2026-05-04T12:15:00.000Z",
    "details": { … }   // optionnel
  }
}

SDK Node.js

npm install @agentgate/node
import { AgentGate } from "@agentgate/node";

const client = new AgentGate({ apiKey: process.env.AGENTGATE_KEY! });

const intent = await client.paymentIntents.submit({
  amount_minor: 24_900,
  currency: "EUR",
  beneficiary: { name: "AWS", account_identifier: "DE12500105170648489890" },
  category: "infrastructure",
  memo: "Facture mensuelle",
});

if (intent.decision === "REJECTED") {
  console.log("Bloqué :", intent.decisionReason);
  return;
}

if (intent.decision === "REQUIRES_HUMAN_APPROVAL") {
  // SSE — bloque jusqu'à la décision humaine (Option C)
  await client.paymentIntents.waitForDecision(intent.id, { timeoutMs: 600_000 });
}

// ← la décision est maintenant APPROVED
// Appelez votre prestataire de paiement ici (Stripe, Wise, Coinbase, etc.)

await client.paymentIntents.execute(intent.id);

Des questions ? support@agentgate.eu