Une API de paiement conçue pour le code d'agent IA.
Une petite API REST. Webhooks signés. SDK officiels dans cinq langues. Conçu pour que votre agent puisse envoyer et régler des USDC et vérifier les paiements en quelques lignes de code.

L'API Blockchain0x est délibérément petite. Nous ne voulons pas que vous lisiez la documentation pendant une heure pour effectuer votre premier paiement. Nous voulons que vous copiez un extrait, colliez votre clé API et l'exécutiez.
Une petite surface, conçue pour le code d'agent.
Les routes de paiement sont ci-dessous. Les webhooks, les clés API et les permissions de dépense en lecture seule complètent la surface ; le SDK les enveloppe tous.
/v1/paymentsEnvoyez un paiement USDC depuis un portefeuille d'agent/v1/transactions/{id}Récupérez le statut et le hash d'une transaction/v1/payment-requests/{id}/settleRégler une facture avec une preuve sur la chaîne/v1/agents/{id}Récupérez un portefeuille d'agent/v1/agentsCréer un portefeuille d'agentTous signés avec HMAC-SHA256.
Signature dans le X-Blockchain0x-Signature en-tête. Fenêtre de relecture de 5 minutes. Clés d'idempotence sur chaque POST.
payment.receivedUSDC est arrivé dans l'un de vos portefeuilles d'agent
payment.sentun paiement sortant de votre agent a été réglé sur la chaîne
wallet.deployedun portefeuille intelligent d'agent a été déployé
webhook.testune livraison de test que vous avez déclenchée depuis le tableau de bord
Envoyez USDC depuis le portefeuille de votre agent.
from blockchain0x import Client
client = Client(api_key="sk_test_...") # sk_test_ testnet, sk_live_ mainnet
tx = client.payments.create(body={
"agentId": "agt_123",
"to": "0xRecipient",
"amountWei": "10000", # USDC base units (6 decimals): 0.01 USDC
})
print(tx) # may return 503 until the chain adapter is wired for your networkClients typés pour TypeScript et Python.
npm install @blockchain0x/nodeFonctionne avec Node 18+. Types TypeScript natifs.
pip install blockchain0xPython 3.9+. Clients synchrones et asynchrones.
Les corps de requête que le SDK enveloppe.
Voici les entrées vérifiées pour chaque route. Les réponses sont montrées ici en abrégé ; les formes typées complètes se trouvent dans le SDK et la référence API. Les montants sont des unités de base USDC (6 décimales).
/v1/paymentsEnvoyez un paiement USDC (payments.create). amountWei est en unités de base USDC (6 décimales). Peut renvoyer 503 jusqu'à ce que l'adaptateur de chaîne soit câblé.
{
"agentId": "agt_123",
"to": "0xRecipient",
"amountWei": "10000",
"metadata": { "reason": "Research report" }
}{
"txHash": "0xff5...e12"
}/v1/payment-requests/{id}/settleRégler une demande de paiement (facture) créée dans le tableau de bord, avec une preuve sur la chaîne (paymentRequests.settle). Il n'y a pas de route de création - uniquement le règlement.
{
"txHash": "0xff5...e12",
"payerAddress": "0xBuyer...",
"amountUsdcVerified": "0.10"
}{
"txHash": "0xff5...e12"
}/v1/transactions/{id}Récupérez une seule transaction par id (transactions.get).
(no body){
"id": "tx_01J9...",
"txHash": "0xff5...e12"
}/v1/agents/{id}Récupérez un portefeuille d'agent (agents.get). Sa page publique se trouve à wallet.blockchain0x.com/a/{slug}.
(no body){
"id": "agt_01J9QKE...",
"name": "research-bot",
"public_url": "https://wallet.blockchain0x.com/a/research-bot"
}/v1/agents/{id}/spend-permissionsLire les autorisations de dépenses d'un agent. EN LECTURE SEULE via l'API - la création et les modifications sont uniquement dans le tableau de bord.
(no body){
"allowance_wei": "5000000",
"per_tx_wei": "1000000",
"period_seconds": 86400,
"start_at": "2026-05-15T00:00:00Z",
"revoked_at": null
}Vérifiez toujours la signature avant de faire confiance au payload.
Tout le monde peut POST à votre URL de rappel. La signature prouve que l'événement vient réellement de nous.
Chaque livraison porte un X-Blockchain0x-Signature en-tête (t=<unix>,v1=<hex>) - un HMAC-SHA256 sur la chaîne `${t}.${rawBody}` avec votre secret de webhook, dans une fenêtre de relecture de 5 minutes. Dans Node, webhooks.verify de @blockchain0x/node le fait et renvoie une union discriminée sur laquelle vous branchez. Dans d'autres langages, calculez le même HMAC et comparez en temps constant. Lisez le corps RAW, pas une copie analysée - la re-sérialisation casse la signature.
import express from "express";
import { webhooks } from "@blockchain0x/node";
const app = express();
// Capture the RAW body. The HMAC is over the exact bytes on the wire.
app.use(express.raw({ type: "application/json" }));
app.post("/webhooks/payment", (req, res) => {
const result = webhooks.verify({
headers: req.headers,
rawBody: req.body, // Buffer, raw bytes
secret: process.env.BLOCKCHAIN0X_WEBHOOK_SECRET!,
});
if (!result.ok) return res.status(400).json({ code: result.code });
// result.eventType is "payment.received" | "payment.sent" | ...
handleEvent(result);
res.status(200).send("ok");
});import hmac, hashlib, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["BLOCKCHAIN0X_WEBHOOK_SECRET"].encode()
@app.post("/webhooks/payment")
def receive():
raw = request.get_data() # RAW bytes - do not parse first
sig = request.headers.get("X-Blockchain0x-Signature", "")
ts = request.headers.get("X-Blockchain0x-Timestamp", "")
# Header is "t=<unix>,v1=<hex>"; some proxies send bare hex + the ts header.
parts = dict(p.split("=", 1) for p in sig.split(",") if "=" in p)
t, v1 = parts.get("t", ts), parts.get("v1", sig)
want = hmac.new(SECRET, t.encode() + b"." + raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(want, v1) or abs(time.time() - int(t)) > 300:
abort(401)
handle_event(request.headers.get("X-Blockchain0x-Event-Type"), request.get_json())
return "ok", 200Le secret du webhook est retourné une fois lorsque vous créez ou faites tourner le webhook (webhooks.rotateSecret), et BLOCKCHAIN0X_WEBHOOK_SECRET est l'endroit où votre gestionnaire le lit. La rotation invalide l'ancien secret, donc coordonnez le déploiement : définissez le nouveau secret dans l'environnement de votre serveur, déployez, puis faites tourner. Les événements expédiés sont payment.received, payment.sent, wallet.deployed et webhook.test - branchez-vous sur le type d'événement, ignorez le reste.
Réessayez en toute sécurité. L'API ne paiera pas deux fois.
Les codes d'agent réessaient. Les réseaux perdent des connexions. Les LLM décident d'appeler l'outil deux fois. Pour sécuriser cela, envoyez un Idempotency-Key en-tête sur le POST. payments.create dans le SDK crée automatiquement un stable pour vous, donc un appel réessayé se réduit à une seule soumission sur la chaîne au lieu de payer deux fois. Remplacez-le par votre propre clé lorsque vous souhaitez dédupliquer la même opération logique à travers les processus.
curl -X POST https://api.blockchain0x.com/v1/payments \
-H "Authorization: Bearer $BLOCKCHAIN0X_API_KEY" \
-H "Idempotency-Key: 8e2c3a40-pay-vendor-once" \
-H "Content-Type: application/json" \
-d '{ "agentId": "agt_123", "to": "0xRecipient", "amountWei": "10000" }'- Premier appel : soumet le paiement, renvoie la transaction.
- Réessayez avec la même clé : se réduit à une seule soumission on-chain au lieu de payer deux fois.
- Le SDK s'en occupe : payments.create génère automatiquement une clé d'idempotence stable, donc un appel réessayé est sûr dès le départ.
- Remplacez-le : passez votre propre clé lorsque vous souhaitez dédupliquer la même opération logique entre les processus.
Le modèle recommandé est de générer un UUID par opération logique dans votre code d'agent (par exemple, un UUID par "payer le fournisseur X pour la commande Y") et de le réutiliser à travers les réessais jusqu'à ce que l'opération réussisse. Les SDK officiels en génèrent automatiquement un pour payments.create si vous ne le spécifiez pas.
Lisez votre limite à partir de la réponse, pas d'un tableau.
Les limites s'adaptent à votre plan. Plutôt que de coder en dur des chiffres qui dérivent, chaque réponse vous indique où vous en êtes et les SDK gèrent le retour pour vous.
En-têtes sur chaque réponse de succès
X-RateLimit-Limit: le tarif stable de votre planX-RateLimit-Remaining: combien d'appels restants dans cette fenêtreX-RateLimit-Reset: secondes unix lorsque la fenêtre se réinitialise
Lorsque vous atteignez le plafond (HTTP 429)
- La réponse inclut
Retry-Afteren secondes - Les SDK officiels réessaient sur 429 et 5xx avec un retour exponentiel, honorant Retry-After
- La plupart des codes ne gèrent jamais 429 manuellement car le SDK le fait déjà
Parle x402 couramment. Fonctionne sans aussi.
x402 est le protocole ouvert pour les paiements natifs HTTP. Le principe : toute API qui renvoie 402 Payment Required peut annoncer des exigences de paiement dans la réponse, et tout client qui comprend la spécification peut payer et réessayer - pas d'inscription, pas de clé API, pas de négociation hors bande. Blockchain0x expédie de véritables packages x402 : un client côté paiement et des adaptateurs de serveur côté réception. Le seul schéma aujourd'hui est exact-usdc, sur Base.
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"version": 1,
"resource": "https://api.example.com/paid-endpoint",
"accepts": [
{ "scheme": "exact-usdc", "network": "eip155:8453" }
]
}Ce que fait l'appelant de l'agent
- Lit le corps 402: version 1, la ressource, et un accepts[] non vide d'exigences de paiement (scheme exact-usdc, network eip155:8453 pour Base).
- Crée un paiement et renvoie la requête avec un en-tête X-Payment: exact-usdc:<base64(json)>.
- Côté paiement, createX402Client({ sdk }) de @blockchain0x/x402 le fait pour vous - il répond automatiquement aux 402.
- Votre serveur vérifie l'en-tête X-Payment et exécute la requête d'origine.
Les deux côtés, vrais packages
Du côté du paiement, createX402Client({ sdk }) de @blockchain0x/x402 enveloppe fetch et répond automatiquement aux 402. Du côté de la réception, createX402Plugin (Fastify) et createX402Middleware (Express) créez vos propres points de terminaison. Ou sautez x402 et utilisez directement l'API REST - les deux se composent, donc vous pouvez ajouter x402 lorsque vous êtes prêt.