Skip to main content

Payments and Refunds

This page covers what's specific to paying for a job with x402: how a quote is priced, the time windows that apply, what a declined payment looks like, how to recover a pending purchase, and when the service refunds you. A quote uses the pay-as-you-go rates on pricing. Subscription prices and discounts don't apply.

Quotes​

An unpaid request creates a quote and returns 402. The quote's resource.url carries a purchase_id. The paid request must repeat the same request fields and the quote's resource and accepted values, or the service answers 409.

  • A quote is valid for 300 seconds. The service removes an expired, unpaid quote about an hour later.
  • Unpaid quote requests are limited to about 20 per minute from one IP address. Over the limit, the service answers 429 with Retry-After: 60. Paid requests, replays, and cancellations are never limited.

How the Price Is Computed​

The quote freezes the rates, your options, and the purchased allowance. The service rounds the duration up to whole minutes, adds the per-minute rate of the core transcription and of each add-on you selected, and rounds the total up to whole cents once. The quote takes its rates from the pay-as-you-go rates on pricing. The smallest quote is one cent, and add-ons have no separate minimum.

For a combined rate R in integer millionths of a dollar per minute:

M = ceil(input_duration / 60)
paid_cents = ceil(M * R / 10_000)
USDC_atomic_amount = paid_cents * 10_000
max_input_duration = min(86_400, 60 * floor(paid_cents * 10_000 / R))

max_input_duration is the purchased allowance. It's the longest file, in seconds, that your payment covers at the frozen rate. The service sets it, and you can't send it.

A 200-second claim with no add-ons is four billable minutes. The quote is one cent (amount is 10000), and the allowance is 300 seconds. A 250-second file succeeds, and so does one of exactly 300 seconds. The same claim with can_parse_words costs two cents (20000) and allows up to 360 seconds, because the allowance depends on the combined rate.

The service measures the actual duration while it processes the file. A shorter file succeeds. A file longer than the allowance fails, and the service refunds you in full. It never truncates the file or charges you again.

Time Windows​

WindowLengthIf it passes
Quote300 seconds from the unpaid requestThe paid request gets 410. After the service removes the quote, it gets 404. The service took no payment.
validBefore6 to 360 seconds after the service's clock when the paid request arrives. Standard clients set it 300 seconds ahead.402 with a fresh PAYMENT-REQUIRED and an error. The service took no payment.
Upload start300 seconds from payment confirmationThe purchase expires and the service refunds it in full. See Upload a File.

Send the paid request right after you sign it, from a machine with an accurate clock.

Declined Payments​

A paid request can also return 402. Its payment header tells you what happened.

Fresh PAYMENT-REQUIRED​

A fresh PAYMENT-REQUIRED header with an error means the service rejected that proof and took no payment. Causes include a facilitator rejection such as insufficient_funds, an invalid authorization, an authorization that doesn't match the quote, and a validBefore outside the allowed window. The quote stays payable until it expires. Fix the cause, then sign the returned requirement again or request a new quote.

PAYMENT-RESPONSE with success: false​

A PAYMENT-RESPONSE header with success: false and an errorReason means the facilitator declined the first settlement before it broadcast a transfer. The body still reports status: "PENDING" and payment_status: "settlement_unknown", but the decline is final. The service took no payment and never submits that proof again.

  • Replaying the proof returns the same 402, then 410 after its validBefore passes.
  • The quote stays bound to that proof, so a new signature for the same quote returns 409.
  • Fix the cause, then request a new quote and pay it.

If Base later shows that transfer anyway, for example because you submitted the authorization yourself, the service treats the purchase as paid. A URL job starts, and an upload purchase expires unused with a full refund.

Recover a Pending Purchase​

A timeout or a lost response doesn't mean the payment failed. Save the exact request and the signed proof before you send the paid request, and keep both private. To recover, send the same request with the same PAYMENT-SIGNATURE header again. The service returns the purchase's current state and never charges you again. Changing any request field returns 409.

A replay returns one of these:

  • A 202 with only purchase_id, status: "PENDING", and a payment_status. The payment isn't confirmed yet. Replay again in a few seconds. The values are in States.
  • A 202 with a job id, or with READY for an upload. The purchase is confirmed.
  • A 402 with a fresh PAYMENT-REQUIRED or a PAYMENT-RESPONSE with success: false. The service took no payment. See Declined Payments.
  • A 404 or 410. The service took no payment. Request a new quote.

Reuse the proof. Don't pay again to resolve a pending answer.

A URL purchase also starts its job without a replay, but the service checks pending payments only every few minutes, so a replay gets you the job id sooner. Replay a pending upload purchase at least once a minute, and more often if you can. Its 300-second upload window starts when the payment is confirmed, even if that happens in the background.

A job id with admission_status: "dispatch_pending" means the job exists but the service hasn't confirmed that it started. Keep polling Get a Job, and don't pay or submit again. The service never submits a job twice, and uncertainty alone doesn't trigger a refund.

If a purchase or job stays pending, email support@speechischeap.com with its purchase or job ID.

Refunds​

Refunds return USDC to the paying wallet. The service pays the processing and settlement fees, so they don't reduce a refund.

Excess Refunds​

After a job succeeds, the service recomputes the price from the actual duration with the frozen rate and the same rounding. If you paid more, it refunds the difference. The price you keep rounds up to whole cents, so the refund is always a whole number of cents:

You paidPrice of the actual duration, before cent roundingRefund
$0.12$0.022$0.09
$0.12$0.010$0.11
$0.01$0.006None

The service makes no adjustment before a job succeeds, and it never sends a zero-amount refund.

Full Refunds​

The service refunds the whole payment when:

  • The transcription fails, including a file that is longer than the purchased allowance.
  • The service can't fetch the file after you pay.
  • An upload fails, or an upload purchase isn't used within its start window.
  • You cancel the job and the cancellation is confirmed. See Cancel a Job.

Tracking a Refund​

If you set a webhook_url, the service sends a refund update when a refund is pending, succeeded, or failed. See Webhooks. A succeeded refund means the service issued it, not that your wallet already received it. Allow up to an hour for a refund to arrive. A failed refund remains owed. If a refund hasn't arrived after an hour, email support@speechischeap.com with the purchase or job ID.