“I kicked off an export/render that takes minutes and I need to poll until it's ready”
Poll an API until a long-running job finishes
Schedule a check, and have that check re-schedule itself until the upstream job is done. Fliq drives the polling loop on a timer so your process doesn't have to sit and wait.
You start a long job on a third-party API — a video render, a data export, a batch import — and it returns a task_id that you have to poll until it’s done. Holding a request open or running an in-process timer is fragile. Instead, let Fliq drive the loop: schedule a job that hits your own status-check endpoint, and have that endpoint schedule the next check if the work isn’t finished yet.
The request
Schedule the first check a little in the future. Your check endpoint does the upstream poll and decides whether to enqueue the next one.
# Kick off the first poll, 15s out
curl -X POST https://api.fliq.sh/jobs \
-H "Authorization: Bearer fliq_sk_your_token" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/api/exports/check",
"http_method": "POST",
"scheduled_at": "2026-06-12T10:00:15Z",
"headers": { "Content-Type": "application/json" },
"body": "{\"task_id\":\"task_abc\"}",
"max_retries": 3
}' // Your /api/exports/check handler:
export async function POST(req) {
const { task_id } = await req.json();
const status = await checkUpstream(task_id); // "running" | "done"
if (status === "done") {
await onExportReady(task_id);
return Response.json({ done: true });
}
// Not ready — schedule the next poll 15s out.
await fetch("https://api.fliq.sh/jobs", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.FLIQ_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://yourapp.com/api/exports/check",
http_method: "POST",
scheduled_at: new Date(Date.now() + 15_000).toISOString(),
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ task_id }),
max_retries: 3,
}),
});
return Response.json({ done: false });
} The loop ends when your handler sees done and simply doesn’t schedule another check.
What Fliq handles for you
- The timer. Each poll is a real scheduled fire — no process needs to stay awake between checks, which suits serverless and Workers perfectly.
- Retries on the check itself. If your status endpoint is briefly down when a poll fires,
max_retriescovers it; the loop doesn’t break on a transient blip. - History of every poll. Each check is a recorded execution, so a runaway loop or a stuck upstream is visible rather than mysterious.
- A natural backoff. Widen the interval each time (
15s,30s,60s) by computingscheduled_atfrom an attempt counter you carry in the body.
Related
- Delay a job N hours — the durable one-off this builds on
- Jobs & Schedules — the job lifecycle
Reference: /docs/jobs-and-schedules