GuidesAI APIS

Replicate API from browser JavaScript

Browsers block every call to api.replicate.com: on 28 October 2026 its preflight returned 200 without an Access-Control-Allow-Origin header, and its 401 responses had none either. The free cors.dev proxy cannot help, because it allows only GET and HEAD and refuses the Authorization header with 400; cors.dev Pro ($5 a month for 500,000 requests, 7-day trial with 1,000 requests, no card) forwards the POST and your r8_ token from origins you register. Output files on replicate.delivery send Access-Control-Allow-Origin: *, so you load them directly.

Why the browser blocks api.replicate.com

Probes sent on 28 October 2026 from Origin: https://example.com:

  • The preflight for POST https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions answered 200 without Access-Control-Allow-Origin.
  • The POST itself with a test token answered 401 (application/problem+json) without Access-Control-Allow-Origin.
  • GET https://api.replicate.com/v1/predictions/{id} also answered 401 without Access-Control-Allow-Origin.

With no Access-Control-Allow-Origin on any of them, the browser blocks every call before your script can read the status or the body. Your code only sees TypeError: Failed to fetch.

What the free proxy does with Replicate

The free tier at https://proxy.cors.dev/ needs no signup or key and allows about 600 requests a minute per IP, but only GET and HEAD. A POST https://proxy.cors.dev/https://api.replicate.com/... answers 405 method_not_allowed with Allow: GET, HEAD, OPTIONS, and an Authorization header answers 400 header_not_allowed.

A GET for a prediction through the free proxy, without a token, returns Replicate's 401 with CORS headers attached. Your code can read that error, but it is useless without the token, and the free tier will not forward one in a header.

Create and poll a prediction through cors.dev Pro

  1. Create a Connection

    sign in at cors.dev with Google, start the 7-day trial (1,000 requests, no card) or cors.dev Pro ($5 a month for 500,000 requests), and create a Connection that lists your exact page origins and api.replicate.com. Its key goes in X-Cors-Key: a publishable identifier that only works from those origins. A wrong key answers 401 invalid_key.

  2. Start the prediction

    POST to https://proxy.cors.dev/https://api.replicate.com/v1/models/{owner}/{name}/predictions with {"input": {...}} for official models, or to /v1/predictions with {"version": ..., "input": {...}} for others, sending X-Cors-Key, Content-Type and Authorization: Bearer r8_.... The preflight answered 204 and allows GET, HEAD, POST, PUT, PATCH and DELETE. Bodies are capped at 1 MiB, so pass large input files as URLs.

  3. Poll until it finishes

    read id, status and urls.get from the response, then poll GET /v1/predictions/{id} through the proxy until status moves from starting or processing to succeeded, failed, canceled, or aborted. When black-forest-labs/flux-schnell succeeds, output comes back as an array of image URLs.

Create a prediction through cors.dev Pro and poll it
const PROXY = 'https://proxy.cors.dev/';
const CORS_KEY = 'YOUR_CONNECTION_KEY'; // publishable, works only from your registered origins

async function replicate(path, token, init = {}) {
  const res = await fetch(PROXY + 'https://api.replicate.com/v1/' + path, {
    ...init,
    headers: {
      'X-Cors-Key': CORS_KEY,
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  });
  if (!res.ok) {
    throw new Error(`HTTP ${res.status}: ${res.headers.get('X-Cors-Error') ?? (await res.text())}`);
  }
  return res.json();
}

async function generate(prompt, token) {
  let prediction = await replicate('models/black-forest-labs/flux-schnell/predictions', token, {
    method: 'POST',
    body: JSON.stringify({ input: { prompt } }),
  });

  while (!['succeeded', 'failed', 'canceled', 'aborted'].includes(prediction.status)) {
    await new Promise((resolve) => setTimeout(resolve, 1500));
    prediction = await replicate(`predictions/${prediction.id}`, token);
  }

  if (prediction.status !== 'succeeded') throw new Error(prediction.error ?? prediction.status);
  return prediction.output;
}

const userToken = prompt('Your Replicate API token');
const [imageUrl] = await generate('a red bicycle', userToken);

Every poll is one proxied request and counts against your cors.dev allowance. cors.dev Pro allows 3,000 requests a minute per account and 100 in flight; the trial allows 600 a minute and 10 in flight. Proxy errors arrive in the X-Cors-Error header:

  • invalid_key or origin_not_allowed: check X-Cors-Key and the Connection's origins; scheme, host and port must match exactly.
  • target_not_allowed: enable api.replicate.com on the Connection.
  • request_too_large: the body is over 1 MiB.
  • upstream_timeout: Replicate took longer than the 30-second deadline.
  • rate_limited or quota_exceeded: a 429; wait for Retry-After, which your code can read.

Skip sync mode and poll

Replicate's sync mode, the Prefer: wait header, holds the create request open until the prediction finishes: 60 seconds by default, or Prefer: wait=n with n from 1 to 60. cors.dev ends every upstream request after 30 seconds, on the free tier and on Pro, so do not depend on sync mode through the proxy. Create the prediction and poll; the Cancel-After header sets a prediction deadline from 5 seconds to 24 hours.

Replicate's docs suggest polling every 1 to 2 seconds until the prediction succeeds or fails. Replicate's own rate limits are 600 requests a minute for creating predictions and 3,000 a minute for all other endpoints; excess requests get 429.

What each status means for the polling loop:

  • starting: the model is booting; if this lasts more than a few seconds, a new worker is usually cold-booting. Keep polling.
  • processing: the model is running. Keep polling; predictions time out after 30 minutes of running.
  • succeeded: read output.
  • failed: read error.
  • canceled: cancelled by you, or past its Cancel-After deadline after it started.
  • aborted: past its deadline before it started; Replicate does not charge for it.

To stop a prediction early, send POST /v1/predictions/{id}/cancel through the same proxy route. Replicate can also POST results to a webhook URL, but that needs an HTTPS server to receive it, so browser code polls.

Output files on replicate.delivery

Generated files are served from replicate.delivery, not api.replicate.com. On 28 October 2026 a sample output, https://replicate.delivery/.../out-0.webp, answered 200 with Access-Control-Allow-Origin: *, and its preflight allowed GET. Fetch outputs directly, no proxy needed, or put the URL in an <img> tag.

For predictions made through the API, Replicate deletes inputs, outputs, and logs after one hour. If you want to keep an output file, download it before that hour is up.

Fetch an output file from replicate.delivery directly
async function keepOutput(outputUrl) {
  const res = await fetch(outputUrl);
  if (!res.ok) throw new Error(`Output HTTP ${res.status}`);
  return URL.createObjectURL(await res.blob());
}

const img = document.createElement('img');
img.alt = 'Generated image';
img.src = await keepOutput(imageUrl);
document.body.append(img);

What Replicate costs

Replicate's pricing page, checked 28 October 2026, bills some official models per output image and other models per second of hardware time:

Replicate prices, checked October 2026
Model or hardwarePriceBilled per
flux-schnell$3.00 per 1,000 imagesOutput image
flux-dev$0.025 per imageOutput image
flux-1.1-pro$0.04 per imageOutput image
ideogram-v3-quality$0.09 per imageOutput image
recraft-v3$0.04 per imageOutput image
CPU$0.000100 a second, $0.36 an hourSecond of run time
Nvidia T4 GPU$0.000225 a second, $0.81 an hourSecond of run time
Nvidia L40S GPU$0.000975 a second, $3.51 an hourSecond of run time
Nvidia A100 80GB GPU$0.001400 a second, $5.04 an hourSecond of run time
Nvidia H100 GPU$0.001525 a second, $5.49 an hourSecond of run time

Public models bill only active processing time, while setup and idle time are free. You can also run select models free before Replicate asks you to set up billing.

Keep your token out of shipped code

Replicate tokens start with r8_ and act on your account and billing. Any key in browser code, in a query string or a header, is visible to every visitor in DevTools; neither cors.dev nor X-Cors-Key hides or protects it.

Keep your own production token on a backend. Calling Replicate from the browser through cors.dev Pro fits internal tools, prototypes and apps where each user pastes their own token (bring your own key).

Good questions.

Does the Replicate API send CORS headers?

No. Probes on 28 October 2026 to POST and GET endpoints on api.replicate.com from Origin: https://example.com returned 200 on the preflight and 401 on direct calls, all without Access-Control-Allow-Origin. Because the header is missing, the browser rejects the responses and throws TypeError: Failed to fetch.

Can I call Replicate through the free cors.dev tier?

No, because creating a prediction requires POST and an Authorization header. The free proxy at https://proxy.cors.dev/ only allows GET and HEAD, so a POST gets 405 method_not_allowed and an Authorization header gets 400 header_not_allowed. cors.dev Pro ($5 a month for 500,000 requests, 7-day trial with 1,000 requests, no card) forwards the POST and the Authorization: Bearer r8_... header from origins you register.

Why shouldn't I use the Prefer: wait header through the proxy?

Replicate's Prefer: wait header holds the prediction request open for up to 60 seconds by default (or 1 to 60 seconds with Prefer: wait=n). cors.dev cuts off every upstream request after 30 seconds, so a slower prediction will time out at the proxy before Replicate answers. Create the prediction first and poll GET /v1/predictions/{id} every 1 to 2 seconds instead.

How long do Replicate output URLs stay live?

For predictions created through the API, Replicate deletes inputs, outputs, and logs after one hour. Output files on replicate.delivery include Access-Control-Allow-Origin: * and allow GET on preflight, so your browser code can fetch the file directly without the proxy and save it before it expires.

How much does it cost to generate images on Replicate?

Per-image prices checked on 28 October 2026 are $3.00 per 1,000 images for flux-schnell, $0.025 per image for flux-dev, $0.04 for flux-1.1-pro and recraft-v3, and $0.09 for ideogram-v3-quality. Other models charge per second of active hardware time, for example $0.000100 a second on CPU, $0.000225 on an Nvidia T4, $0.000975 on an L40S, $0.001400 on an A100 80GB and $0.001525 on an H100. Setup and idle time on public models are free, and you can try select models for free before setting up billing.