# x402 API The x402 API is a speech-to-text API for AI agents. It transcribes audio and video files asynchronously and charges each job to the agent's wallet in USDC on Base, with no account or API key. Send the job request, get `402 Payment Required` with the price, pay it with an x402 client, and then read the result for free or receive it by webhook. A job accepts the same options as a [Jobs API](../jobs-v2/index.md) job, except the progress stream. ## Why x402 The x402 API enables an application or autonomous AI agent to pay for transcription per job directly from its own wallet, using native USDC on the Base network. Because payment occurs over standard HTTP 402 responses, you do not need to create a Speech is Cheap account, enter a credit card, commit to a monthly subscription, or store API keys in your environment. Pricing follows standard pay-as-you-go rates, and any unused purchased time or failed jobs are automatically refunded to the paying wallet. This makes x402 a good fit for autonomous agents with independent budgets, multi-tenant agent workflows, and ad-hoc scripts where ongoing account maintenance is undesirable. An API key is the better choice when your workload benefits from centralized account management. High-volume users can lower per-minute costs by choosing the monthly subscription plan. API keys are also required if you want the Server-Sent Events progress stream (x402 supports only polling and webhooks) or need the synchronous Edge API for instant short-audio responses. Finally, API keys provide consolidated usage metrics and Stripe invoices through the Dashboard. ## How It Works 1. **Request a quote.** `POST` your job to `https://api.speechischeap.com/v2/x402/jobs/` without payment. The service answers `402 Payment Required` with the price and the address to pay in a `PAYMENT-REQUIRED` header. A quote is free and valid for 300 seconds. 2. **Pay.** Your x402 client signs a USDC transfer authorization for the quoted amount. Send the same request again with the signed proof in a `PAYMENT-SIGNATURE` header. 3. **Confirm.** The service settles the payment on Base and answers `202 Accepted`. Confirming the payment takes a few seconds, so the first answer usually reports `payment_status: "stripe_pending"` and has no job `id`. Send the same request and proof again until the answer has an `id`. A replay never charges you again. 4. **Transcribe.** A URL job starts as soon as the payment is confirmed. For an upload, the answer is `READY` with a one-use `upload_token`. Send the file with it to `https://upload.speechischeap.com/v2/x402/jobs/` within 300 seconds. 5. **Receive the result.** Read it with a free `GET` request, or receive it at your `webhook_url`. If a job fails, is canceled, or finishes shorter than you paid for, the service refunds the difference to your wallet. See [Payments and Refunds](./payments.md). ## Network and Asset | Setting | Value | |---------|-------| | Scheme | x402 v2 `exact` (EIP-3009 `transferWithAuthorization`) | | Network | Base mainnet, `eip155:8453` | | Asset | Native USDC, `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | | Amount | USDC atomic units with six decimals, so `10000` is $0.01 | The service accepts no other network or token. Your wallet needs only USDC: the service submits the transfer and pays the network fee. ## What You Need - An x402 v2 client that supports the `exact` scheme on Base, such as `@x402/fetch`. - A wallet with USDC on Base and a signer for EIP-712 typed data. Canceling a job also needs EIP-191 message signing. - The duration of each file in seconds. The service doesn't measure a file before you pay. For example, `ffprobe -v error -show_entries format=duration -of csv=p=0 audio-file.mp3` prints it. - Optionally, an endpoint for [webhooks](./webhooks.md). You need no Speech is Cheap account, API key, or card. ## Authentication There's no API key. The payment authorizes a job, and the paying wallet's signature authorizes canceling it. Reading a job needs no authentication. ## Endpoints The API uses two hosts, `https://api.speechischeap.com/v2/` and `https://upload.speechischeap.com/v2/`. | Method | URL | Page | |--------|-----|------| | `POST` | `https://api.speechischeap.com/v2/x402/jobs/` | [Create a Job from a URL](./create.md), or the first step of [Upload a File](./upload.md) with `input_type` set to `upload` | | `POST` | `https://upload.speechischeap.com/v2/x402/jobs/` | [Upload a File](./upload.md) | | `GET` | `https://api.speechischeap.com/v2/jobs/:job_id` | [Get a Job](./read.md) | | `DELETE` | `https://api.speechischeap.com/v2/x402/jobs/:job_id` | [Cancel a Job](./delete.md) | ## States ### Before a Job Exists A paid request that has no job `id` yet returns a purchase `status`: | Status | Meaning | What to do | |--------|---------|------------| | `PENDING` | The payment isn't confirmed. `payment_status` says where it stands. | Send the same request and proof again. | | `UNCLAIMED` | A URL purchase is paid and waiting to start. | Send the same request and proof again. | | `READY` | An upload purchase is paid. The answer has `upload_url` and `upload_token`. | [Send the file](./upload.md) within 300 seconds. | | `CLAIMED` | An upload is in progress. | Wait for the upload to finish. | | `EXPIRED` | A paid purchase wasn't used in time, for example an upload that didn't start within 300 seconds. The service refunds it in full. | Start a new purchase. | | `FAILED` | The purchase failed before a job was created, for example because the file URL was unreachable or an upload failed. The service refunds it in full. | Fix the cause and start a new purchase. | While the status is `PENDING`, `payment_status` is one of these: | Payment status | Meaning | |----------------|---------| | `quoted` | The service hasn't finished verifying the proof. Another request may be verifying it now. | | `settling` | The service is submitting the transfer on Base. | | `settlement_unknown` | The service doesn't yet know whether the transfer succeeded. It keeps checking Base. | | `stripe_pending` | The transfer succeeded and the service is confirming the payment. | ### Job States Once the answer has an `id`, the job's `status` is `PENDING`, `COMPLETED`, `FAILED`, or `CANCELED`, as in the Jobs API. [Get a Job](./read.md) explains each one. ## Receiving Results - **Poll.** [Get a Job](./read.md) is free and needs no payment, signature, or key. - **Webhook.** Set `webhook_url` and the service sends the job's outcome and any refund updates to it. It retries failed deliveries for up to 24 hours. See [Webhooks](./webhooks.md). The job's `GET` response is the source of truth for its result. ## Runnable Example x402-client.mjs pays for a job with `@x402/fetch`, saves its proof before it pays, and replays a pending payment. Setup and usage are in [Create a Job from a URL](./create.md#example-requests). ## Related Pages - [Input Requirements](../input-requirements.md) lists the duration, size, and URL rules. - [Supported File Types](../types.md) lists the accepted containers and codecs. - [Supported Languages](../languages.md) lists the `language` codes. - [Output and Add-ons](../jobs-v2/output.md) describes the result and its optional fields. - [Errors](../errors.md#x402-api) lists every error message and how to recover.