Skip to main content

Managing Jobs

When you submit a render you get back a job_id. These endpoints let you look that job up later — to check where it is in the pipeline, see why it failed, or find the clip it produced — and to re-run it if you want a fresh render.

The recommended way to learn a job finished is the outcome webhook: we call you, so you don't have to poll. Fetching the job is the pull-based alternative (and a way to reconcile state if you ever miss a webhook or need to confirm a job's current status).

All job endpoints authenticate the same way as job submission — Authorization: Bearer YOUR_API_KEY (see Authentication) — and only ever act on jobs owned by the authenticated account. A job id that doesn't exist, or belongs to another account, returns 404. Either API key (metered or reserved) can read and resubmit any of your own jobs, regardless of which key originally submitted it.


The job object

The get endpoint returns the job as a JSON object:

{
"id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"status": "done",
"priority": false,
"fps": 30,
"resolution": 1080,
"clip_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"error_code": null,
"created_at": "2026-08-06T12:00:00.000Z",
"finished_at": "2026-08-06T12:03:20.000Z",
"payload": {
"demo_url": "https://cdn.example.com/matches/abc123.dem",
"steam64_id": "76561198000000000",
"round": 5,
"resolution": 1080,
"idempotency_key": "3f8c1a2b-9d4e-4f6a-bc12-7e0a5d9c1234",
"extras": "{\"gameId\":\"0408314d-53fa-4fa6-8770-c890171319b8\"}"
}
}
FieldTypeDescription
idstringThe job's UUID — the job_id you got back from POST /api/clips.
statusstringWhere the job is in the pipeline. See Job status below.
prioritybooleantrue if this was a reserved (priority) job, false for a best-effort one. Set from the key that submitted it.
fpsinteger | nullRecording framerate. null when you didn't specify one at submit — the renderer applies its default.
resolutionintegerRender resolution.
clip_idstring | nullThe clip this job produced, once it succeeds. null until then (and on a failed job). Look it up via GET /api/clips/:id.
error_codestring | nullWhy the job failed. null unless status is retrying or error. Same values as the webhook — see Error codes.
created_atstringISO 8601 timestamp of when the job was submitted.
finished_atstring | nullISO 8601 timestamp of when the job reached a terminal state (done or error). null while it's still in flight or waiting to retry.
payloadobjectThe render request as it was stored — see The payload object below.

The payload object

payload echoes back the request body the job was submitted with, as a nested JSON object: the mode fields (demo_url plus steam64_id/round, or timeline) and any render options you set (fps, commands, watermark_image_id, hud_killfeed, …), alongside server-normalized copies of resolution and the job's idempotency_key. Read Submitting Render Jobs for what each field means.

One field is transformed on the way out: extras is returned as a string — the opaque value you sent, serialized to JSON text (JSON.parse it to recover your original value), or null if you didn't send any. Note this differs from the outcome webhook, which echoes extras back with its original JSON type.

Job status

status moves through the render pipeline:

StatusMeaning
pendingQueued, waiting for a render slot. It hasn't started yet.
prefetchClaimed by a render host, which is downloading the demo before rendering.
renderBeing rendered right now inside CS2.
doneRendered successfully. clip_id points to the finished clip.
retryingThe last attempt hit a transient problem (e.g. a slow demo download) and is queued to run again automatically. error_code says what happened. No action needed — you'll get a done or error outcome eventually.
errorThe job failed for good and will never produce a clip. error_code says why.

Treat retrying as "still on its way", not a failure — only error is terminal. A retrying job sends no webhook; it stays silent until it either succeeds or exhausts its retries and becomes error. See Webhooks for the full outcome model.


Get a job

GET https://dinkem.gg/api/jobs/:id

Returns the job object. Use it to poll a job's status, read its error_code, or find the clip_id it produced.

curl https://dinkem.gg/api/jobs/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d \
-H "Authorization: Bearer YOUR_API_KEY"

Returns 404 if no job with that id belongs to your account.

If you're polling for completion, prefer a webhook where you can — but when you do poll, poll sensibly (e.g. every few seconds, backing off over time), and stop once status is done or error.


Resubmitting a job

POST https://dinkem.gg/api/jobs/:id/resubmit

Re-runs a job you've already submitted, without you having to hold onto and replay the original request body. No request body is needed — the job keeps its original payload (demo, player, render settings) and its webhook destination.

curl -X POST https://dinkem.gg/api/jobs/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/resubmit \
-H "Authorization: Bearer YOUR_API_KEY"

On success returns 200 with the job id — the same id, since the job is re-run in place:

{ "job_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" }

The job is reset to pending and picked up again by the render fleet. When it re-renders it overwrites the original clip (same clip_id) rather than producing a second one, and its outcome webhook fires again for the new result. The previous outcome's undelivered webhooks are canceled.

When you can resubmit:

  • A finished job (done or error) can be resubmitted — this is the main use: retry a job that failed for a reason you've since fixed (e.g. a demo URL that was briefly unreachable), or re-render a clip after a settings change on our end.
  • A retrying job can also be resubmitted — doing so just skips the wait until its next automatic retry.
  • A job that is still in flight (pending, prefetch, or render) cannot be resubmitted, since a render host may be working on it. This returns 409. Wait for it to finish, then resubmit if you still need to.
StatusResponse
Job reset and re-queued200 with { "job_id": "..." }
No job with that id under your account404
Job is still in flight (pending / prefetch / render)409

Resubmit vs. force redo

There are two ways to re-run a job, for two different situations:

  • POST /api/jobs/:id/resubmit (this endpoint) — the simple path. You have a job_id and want to run that exact job again, unchanged. No body, no idempotency key, keeps the original webhook.
  • POST /api/clips with force: true — the path when you want to redo a job and change something about it (a new webhook_url, for instance), or when you track jobs by your own idempotency_key rather than by job_id. It matches on the key and re-applies the new request body.

Both re-run in place and overwrite the original clip; pick whichever matches how you track your jobs.


Resend a webhook

POST https://dinkem.gg/api/jobs/:id/resend-webhook

Re-delivers a finished job's outcome webhook without re-rendering the clip. Use it when your endpoint missed the original — it was down, or kept returning non-2xx until our retries gave up. No request body: we replay the job's most recent outcome (job.completed or job.failed), to the same destination and with the same payload as the original.

curl -X POST https://dinkem.gg/api/jobs/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/resend-webhook \
-H "Authorization: Bearer YOUR_API_KEY"

On success returns 200 with the delivery id of the queued webhook:

{ "delivery_id": "c1a2b3d4-5678-90ab-cdef-1234567890ab" }

That id is the X-Dinkem-Delivery-Id the resent webhook will carry, so you can match the incoming delivery to this call. The resend is a fresh delivery with its own id, not a retry of the original — treat it as a new event and dedupe as usual.

Delivery is asynchronous, exactly like the original: a 200 means the webhook was queued, not that your endpoint has received it. It then follows the same retry schedule as any other webhook.

When you can resend:

  • The job must already have produced an outcome webhook — i.e. it finished (done or error) with a webhook_url set. A job submitted without a webhook_url has nothing to resend.
  • A job still in flight (pending / prefetch / render) has no settled outcome to resend, and returns 409.
StatusResponse
Webhook queued for delivery200 with { "delivery_id": "..." }
No job with that id under your account404
Job is still in flight (pending / prefetch / render)409
Job has no outcome webhook to resend409