# extract.dkta.dev > Clean content extraction for AI agents. Pay per request with x402 on Base, or prepay by card for a bearer API key. ## API ### GET /v1/extract?url=&format= Returns structured content extracted from a public HTTP(S) URL. Authorize with either an x402 v2 micropayment of $0.001 USDC on Base mainnet or a prepaid bearer API key. **Response:** ```json { "title": "Article Title", "byline": "Author Name", "url": "https://...", "content": "# Markdown content...", "length": 4821, "word_count": 800, "extraction_method": "crawl4ai", "lang": "en" } ``` ### POST /v1/extract/batch Batch extract 1 to 5 URLs for a flat $0.005 charge, authorized with x402 on Base or a prepaid bearer API key. **Request body:** ```json { "urls": ["https://example.com/article1", "https://example.com/article2"], "format": "markdown" } ``` **Response:** ```json { "results": [ { "title": "Article Title", "byline": "Author Name", "url": "https://example.com/article1", "content": "# Markdown content...", "length": 4821, "word_count": 800, "extraction_method": "crawl4ai", "lang": "en" }, { "url": "https://example.com/article2", "error": "upstream returned 404" } ] } ``` The batch returns HTTP 200 and settles the flat payment even when per-URL upstream or extraction errors are included inline. Invalid request shape or target URLs are rejected before payment with HTTP 400. ## Response fields - `title` — article title (nullable) - `byline` — author/byline (nullable) - `url` — canonical URL of the extracted page - `content` — extracted markdown or plain text - `length` — character count of extracted content - `word_count` — approximate word count - `extraction_method` — `"crawl4ai"` or `"readability"` (which backend was used) - `lang` — detected language code (e.g. `"en"`, `"zh"`) - `error` — present only on per-URL batch failures ## x402 payment Use an x402 v2 client with a self-custodied or managed USDC wallet on Base mainnet (`eip155:8453`). The free HTTP 402 response carries base64 payment requirements and Bazaar discovery metadata in `PAYMENT-REQUIRED`; clients retry with `PAYMENT-SIGNATURE`. Send the same client-generated UUID as `X-Request-ID` on the initial request and paid retry. ```js import { randomUUID } from 'node:crypto' import { x402Client } from '@x402/core/client' import { registerExactEvmScheme } from '@x402/evm/exact/client' import { wrapFetchWithPayment } from '@x402/fetch' import { privateKeyToAccount } from 'viem/accounts' const client = new x402Client() registerExactEvmScheme(client, { signer: privateKeyToAccount(process.env.EVM_PRIVATE_KEY), }) const paidFetch = wrapFetchWithPayment(globalThis.fetch, client) // Single extraction — $0.001 USDC const res = await paidFetch('https://extract.dkta.dev/v1/extract?url=https://example.com', { headers: { 'X-Request-ID': randomUUID() }, }) const { title, content, word_count, extraction_method, lang } = await res.json() // Batch extraction — $0.005 USDC const batchRes = await paidFetch('https://extract.dkta.dev/v1/extract/batch', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Request-ID': randomUUID() }, body: JSON.stringify({ urls: ['https://example.com', 'https://example.org'] }), }) const { results } = await batchRes.json() ``` ## Prepaid API key `GET /v1/credits/checkout` returns a reusable Stripe Payment Link for a new-key purchase of the optional $10 package. It buys 10,000 single extractions, 2,000 batch requests, or any equivalent mix. The success page generates a 256-bit `ext_live_...` candidate locally and submits `{ "session_id": "...", "api_key": "ext_live_..." }` to `POST /v1/credits/claim`. Retry with the same candidate if the response is interrupted; the server stores only its hash. Use the accepted key as: ```http Authorization: Bearer ext_live_... ``` To add the same package to an existing key, call `POST /v1/credits/topups` with that bearer authorization, then open the returned `checkout_url`. Extract authenticates the key and sends Stripe only a random `client_reference_id` bound to that key; neither the key nor its hash appears in the URL. Every successfully paid Checkout Session carrying that reference credits the same existing key. `GET /v1/credits/balance` returns the remaining integer credit units and equivalent request counts. Credits do not expire. Never place the key in a URL or client-side application. ## Validation and billing - Request shape, format, URL scheme, credentials, DNS resolution, and direct private/link-local targets are checked before either payment path. - A single extraction incurs a charge only after success: x402 settlement is skipped and prepaid credits are released on 4xx/5xx. A batch incurs its flat charge on HTTP 200, including when individual results contain inline errors. - Readability fetches pin a validated public address on every redirect hop. The Crawl4AI worker is independently restricted from private and non-routable destinations at the host firewall. ## Pricing - Single extraction: $0.001 USDC via x402, or 1,000 prepaid units - Batch extraction (1 to 5 URLs): $0.005 USDC via x402, or 5,000 prepaid units - Optional prepaid package: $10 USD for 10,000,000 units; no subscription or expiry ## Docs - OpenAPI spec: https://extract.dkta.dev/openapi.json - Interactive docs: https://extract.dkta.dev/docs - x402 protocol: https://x402.org - x402 manifest: https://extract.dkta.dev/.well-known/x402.json - Bazaar metadata: embedded in each x402 v2 `PAYMENT-REQUIRED` challenge