media processing for agents
Not accepting jobs yet. This mainnet gateway is fully deployed but switched off while we finish launch checks — paid endpoints answer 503 service_disabled. Watch this page.

Pay-per-call media processing.

Convert a video with one HTTP call — supply a source URL, or upload the file directly. Payment is $0.05 per conversion in USDC over the x402 protocol. No account, no API key, no invoice.

402 → pay → 202
# 1. ask for the job. no payment yet, nothing charged.
$ curl -sS -D - -o /dev/null -X POST https://ffpipe.dev/v1/convert \
    -H 'content-type: application/json' \
    -d '{"sourceUrl":"https://storage.example.com/clip.mov"}'
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiYWNjZXB0cyI6W3si…  # $0.05 USDC · base

# 2. your x402 client signs that challenge and retries the same request.
$ curl -sS -X POST https://ffpipe.dev/v1/convert \
    -H 'content-type: application/json' \
    -H "payment-signature: $SIGNED_PAYLOAD" \
    -d '{"sourceUrl":"https://storage.example.com/clip.mov"}'
HTTP/2 202
{"jobId":"9f2c…","status":"queued","statusUrl":"https://ffpipe.dev/v1/jobs/9f2c…?t=…"}

# 3. poll the statusUrl (free) until finished, then download resultUrl.

Machine-readable everything: openapi.json · llms.txt

Pricing

EndpointPriceWhat you get
POST /v1/convert $0.05 One video conversion, scaled to fit 1920×1080 by default. Input ≤ 100 MB.
GET /v1/jobs/:id free Status polling, unmetered. Docs, health and this page are free too.

Priced in USDC on base (eip155:8453), x402 exact scheme. Per job, no subscription, no minimum, no account. Failed jobs are refunded as a free retry — see the FAQ.

x402 flow

  1. Ask

    POST the endpoint with no payment header. You get 402 and a PAYMENT-REQUIRED header: base64 JSON naming the scheme, network, asset, amount and our address.

  2. Sign

    Your wallet signs an EIP-3009 TransferWithAuthorization for exactly that amount. Nothing moves on-chain yet, and nothing is held.

  3. Retry with the signature

    Send the identical request again with payment-signature. Any x402 client library does steps 1–3 for you in one call.

  4. We verify, queue, then settle

    The facilitator verifies the payment, we validate your input, stage your source and queue the job — and only then does the payment settle.

  5. Poll and collect

    202 returns a tokenized statusUrl. Poll it at no charge until finished, then download resultUrl within 24 hours.

Code

curl · voucher retry included
# pay + submit (SIGNED_PAYLOAD comes from your x402 client / wallet)
$ curl -sS -X POST https://ffpipe.dev/v1/convert \
    -H 'content-type: application/json' \
    -H "payment-signature: $SIGNED_PAYLOAD" \
    -d '{"sourceUrl":"https://storage.example.com/clip.mov"}'

# poll (free). keep the whole statusUrl: the ?t= token is your receipt.
$ curl -sS "https://ffpipe.dev/v1/jobs/JOB_ID?t=TOKEN"

# if we failed the job, its status carries a retryVoucher — spend it free:
$ curl -sS -X POST https://ffpipe.dev/v1/convert \
    -H 'content-type: application/json' \
    -H "x-retry-voucher: UUID.HMAC" \
    -d '{"sourceUrl":"https://storage.example.com/clip.mov"}'

FAQ

What happens if a job fails?

You get an automatic retry voucher. We charge when we accept a job, so if processing then fails, the failed job's status response carries retryVoucher. Send it back as x-retry-voucher and the retry is free — no payment, no signature. Single use, same endpoint kind, chained up to 3 retries per job. It's the refund; there are no on-chain refunds at these prices. Failures that happen before acceptance (bad body, unfetchable or oversized source) return a non-2xx and are never charged in the first place.

How long do results last?

Download your result within 24 hours of completion. resultUrl and thumbnailUrl are served by this gateway and are re-downloadable at no charge within that window. ffpipe is a processing service, not storage — retrieve what you need promptly.

Which URLs can I send?

Any https URL we can fetch, up to 100 MB. We fetch from datacenter IP ranges, so hosts that block datacenter traffic answer 403 and you get ingest_failed — prefer a presigned URL from storage you control. No IP literals, no internal hostnames, at most 3 redirects. Or upload bytes directly — no hosting needed: send {"upload": true} instead of a sourceUrl and PUT your file to the uploadUrl in the 202 (you have an hour by default; the details are in the spec).

Do I need an account or an API key?

No. The payment is the authorization. Bring a wallet with USDC on base and an x402 client; nothing else exists to sign up for.

How long does a job take?

Jobs are asynchronous — typically a few minutes for a short clip. There is no SLA. If no completion arrives within 6 hours the job is marked error; contact us with the job id if that happens.