{"slug": "build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call", "title": "Build a KYB agent in 20 lines no API key, the agent pays per call", "summary": "A developer built a Know Your Business (KYB) agent in ~20 lines of TypeScript that verifies French companies using a pay-per-call API without requiring an API key or account. The agent uses the x402 protocol to handle HTTP 402 Payment Required responses, signing USDC authorizations to pay $0.15 per request. The endpoint consolidates six data sources including registry identity, officers, legal announcements, filed accounts, and sanctions screening against five official lists.", "body_md": "AI agents have a boring problem: they can't sign up for things. Every\n\ninteresting API sits behind an email verification, a credit-card form and an\n\nAPI key — three things a headless agent can't do. I ran into this building my\n\nown agents, so I ended up building an API the other way round, and this is the\n\n20-line version of what it makes possible.\n\nWe'll build a working KYB (Know Your Business) agent in ~20 lines of\n\nTypeScript. It verifies any French company — identity, officers, insolvency\n\nalerts, filed financials, sanctions screening — and it pays for what it uses,\n\nper call, in USDC. No account anywhere.\n\n```\ncurl -i \"https://api.sirenic.eu/v1/kyb/552032534\"\n```\n\nYou get `HTTP 402 Payment Required`\n\n. The `PAYMENT-REQUIRED`\n\nheader is\n\nbase64 JSON: price (`$0.15`\n\n→ `150000`\n\natomic USDC units), the receiving\n\naddress, the official USDC contract and the network (Base). Nothing was\n\ncharged — quotes are free.\n\nCreate a throwaway wallet (MetaMask works), export the private key, and\n\nfund it with a couple of dollars of USDC on **Base** (any exchange can\n\nwithdraw to Base). The `exact`\n\npayment scheme uses signed authorizations,\n\nso the client never pays gas — USDC is all the wallet needs. The whole\n\ntutorial costs $0.15.\n\n```\nnpm install @x402/fetch @x402/core @x402/evm viem tsx\nexport TEST_WALLET_KEY=0x...\njs\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { wrapFetchWithPayment } from \"@x402/fetch\";\nimport { x402Client } from \"@x402/core/client\";\nimport { registerExactEvmScheme } from \"@x402/evm/exact/client\";\n\nconst siren = process.argv[2] ?? \"552032534\";\nconst client = new x402Client();\nregisterExactEvmScheme(client, {\n  signer: privateKeyToAccount(process.env.TEST_WALLET_KEY as `0x${string}`),\n});\nconst payingFetch = wrapFetchWithPayment(fetch, client);\n\nconst kyb = await (await payingFetch(\n  `https://api.sirenic.eu/v1/kyb/${siren}`,\n)).json() as Record<string, any>;\n\nconsole.log(`Company : ${kyb.identite.denomination} (${kyb.siren}) — ${kyb.identite.etat_administratif}`);\nconsole.log(`Officers: ${kyb.identite.dirigeants?.length ?? 0} | VAT: ${kyb.tva_intracommunautaire}`);\nconsole.log(`Alerts  : ${kyb.alertes_bodacc.procedures_collectives?.length ?? \"n/a\"} insolvency proceedings`);\nconsole.log(`Sanctions screening: ${kyb.criblage_sanctions.statut}`);\nconsole.log(`Completeness: ${kyb.score_completude}/100`);\n```\n\nRun it:\n\n``` bash\n$ npx tsx kyb-agent.ts 552032534\nCompany : DANONE (552032534) — actif\nOfficers: 13 | VAT: FR27552032534\nAlerts  : 0 insolvency proceedings\nSanctions screening: correspondances_a_verifier\nCompleteness: 100/100\n```\n\nThat's the whole agent. `wrapFetchWithPayment`\n\nintercepted the 402, signed\n\na $0.15 USDC authorization, retried, and the API released the response once\n\nthe settlement was confirmed on-chain.\n\nThe `/v1/kyb/{siren}`\n\nendpoint consolidates six sources server-side:\n\nregistry identity and officers, BODACC legal announcements, filed accounts,\n\nand a fuzzy sanctions screening of the company name **and every officer**\n\nagainst the five official lists (UN, EU, OFAC, UK, French asset-freeze\n\nregister). Matches come back with a 0-100 confidence score and the matched\n\nalias — never a bare yes/no, because \"Emmanuel Macron vs. Emmanuel Sultani\n\nMakenga\" is exactly the kind of thing you want a human to look at.\n\nTwo production details worth stealing for your own paid APIs:\n\nThe same API is an MCP server — Claude and Cursor can use it directly:\n\n```\nclaude mcp add --transport http sirenic https://api.sirenic.eu/mcp\n```\n\nEach tool takes an optional `x_payment`\n\nparameter with the same quote/sign/\n\nretry loop.\n\nData is official open data redistributed as published; responses carry\n\nsource and disclaimer fields. Screening output is a decision aid, not a\n\ncompliance opinion.", "url": "https://wpnews.pro/news/build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call", "canonical_source": "https://dev.to/sirenic/build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call-334p", "published_at": "2026-07-18 17:06:30+00:00", "updated_at": "2026-07-18 17:30:57.659399+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "artificial-intelligence"], "entities": ["Sirenic", "DANONE", "Base", "MetaMask", "USDC", "OFAC", "UN", "EU"], "alternates": {"html": "https://wpnews.pro/news/build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call", "markdown": "https://wpnews.pro/news/build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call.md", "text": "https://wpnews.pro/news/build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call.txt", "jsonld": "https://wpnews.pro/news/build-a-kyb-agent-in-20-lines-no-api-key-the-agent-pays-per-call.jsonld"}}