Analytics
Jobs
Poll the status of an asynchronous job and download its result.
/v1/jobs/get-by-idWork that takes longer than a request runs as a job. Today that means
analytics exports: the export endpoint returns a
jobId, and this endpoint reports what happened to it.
| Status | Meaning |
|---|---|
inProgress | Still running. Poll again shortly. |
done | Finished. The response carries a url to download. |
failed | The job did not complete. Queue it again. |
Poll on an interval, not in a tight loop
An export takes seconds to minutes depending on the range. Poll every few seconds — continuous polling burns rate limit budget without making the job finish sooner.
async function waitForJob(apiToken, jobId, { intervalMs = 3000, timeoutMs = 300000 } = {}) {
const deadline = Date.now() + timeoutMs
while (Date.now() < deadline) {
const url = new URL('https://api.superfunnel.ai/v1/jobs/get-by-id')
url.searchParams.set('jobId', jobId)
const response = await fetch(url, {
headers: { 'x-api-key': `Bearer ${apiToken}` },
})
if (!response.ok) {
throw new Error(`Request failed with ${response.status}`)
}
const job = await response.json()
if (job.status === 'done') return job
if (job.status === 'failed') throw new Error(`Job ${jobId} failed`)
await new Promise((resolve) => setTimeout(resolve, intervalMs))
}
throw new Error(`Job ${jobId} did not finish in time`)
}Query parameters
jobIdstringrequiredThe `jobId` returned when the job was created.
Response · 200
idstringrequiredtypestringrequiredstatusenumrequired`inProgress` until the job finishes, then `done` or `failed`.
One of: inProgress, completed, failed
urlstringDownload URL for the result. Present once the job is `done`.
createdAtstringupdatedAtstringExample response
{
"id": "JkLmNoPqRsTuVwXy",
"type": "exportAnalytics",
"status": "done",
"url": "https://storage.googleapis.com/...",
"createdAt": "2026-08-11T09:30:00.000Z",
"updatedAt": "2026-08-11T09:31:12.000Z"
}Errors: 400, 401, 404, 405, 429, 500. See Errors for the response shape.