Skip to content
SimpleCold

API docs

Endpoints

Get the job status

On this page

Returns a bulk job's status, progress and an estimate of when it will finish. Poll it until the job is COMPLETED.

GET/api/v1/api-validation/bulk/:id/status

Path parameters

ParameterTypeRequiredDescription
idstringYesThe job id returned by the upload.

Request

Request
curl "https://simplecold.com/api/v1/api-validation/bulk/b0f6c2a4-6a3e-4c55-9d1e-2f8a7c1b9e40/status" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200
{
  "code": "SUCCESS",
  "message": "Successfully performed operation.",
  "payload": {
    "status": "IN PROGRESS",
    "totalProcessed": 2100,
    "progressPercent": 43.6,
    "etaSeconds": 310,
    "lastUpdatedAt": "2026-07-30T09:19:40.002Z",
    "nextUpdateAt": "2026-07-30T09:20:40.002Z",
    "queuedChunks": 0
  },
  "requestId": "7e21..."
}

When every address has a result, status becomes COMPLETED and progressPercent reaches 100.

The status response does not repeat the job's name or totals. Keep those from the upload response.

Response fields

FieldTypeDescription
statusstringIN PROGRESS, COMPLETED, CANCELING, CANCELED, FAILED or QUEUE. Note the space in IN PROGRESS. See job statuses.
totalProcessednumberAddresses with a result so far.
progressPercentnumbertotalProcessed as a percentage of the job's addresses, to one decimal place.
etaSecondsnumber | nullEstimated seconds left while the job is running, or null when there isn't enough data for an estimate yet (and once the job has finished).
lastUpdatedAtstring | nullWhen the progress numbers last changed.
nextUpdateAtstring | nullWhen the progress numbers will next change. Polling before this time returns the same numbers.
queuedChunksnumberParts of the job still waiting to be sent for checking.

Polling

Progress only moves at nextUpdateAt, and status has its own limit of 120 requests per minute per API key. So wait until nextUpdateAt (plus a second), with a floor of about 5 seconds and a ceiling of about 2 minutes. If nextUpdateAt is null, use etaSeconds capped at a minute, or 15 seconds.

Stop when status is COMPLETED or CANCELED (you can download from both) or FAILED (retry the job from the dashboard).

const API = "https://simplecold.com/api/v1";
const auth = { Authorization: `Bearer ${process.env.SIMPLECOLD_API_KEY}` };
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

function nextDelayMs(p) {
  let wait = 15_000;
  if (p.nextUpdateAt) wait = new Date(p.nextUpdateAt).getTime() - Date.now() + 1_000;
  else if (p.etaSeconds != null) wait = Math.min(p.etaSeconds * 1000, 60_000);
  return Math.min(120_000, Math.max(5_000, wait));
}

export async function waitForJob(id) {
  for (;;) {
    const res = await fetch(`${API}/api-validation/bulk/${id}/status`, { headers: auth });
    if (res.status === 429) {
      await sleep(Number(res.headers.get("retry-after") ?? 60) * 1000);
      continue;
    }
    const body = await res.json();
    if (!res.ok) throw new Error(`status failed: ${body.message}`);
    const p = body.payload;
    console.log(`${p.status} ${p.progressPercent}% eta=${p.etaSeconds ?? "?"}s`);
    if (p.status === "COMPLETED" || p.status === "CANCELED") return p;
    if (p.status === "FAILED") throw new Error("job failed; retry it from the dashboard");
    await sleep(nextDelayMs(p));
  }
}

Errors

HTTPMessageCause
400Job not found.No job with this id in your organization.
401Invalid API key and othersSee authentication errors.
429Rate limit exceeded. Maximum 120 status requests per minute per API key.Over 120 status requests per minute with this API key. Wait Retry-After seconds.

Next

When the job is COMPLETED, download the results.

Get the job status | SimpleCold API docs