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\"}"
}
}
| Field | Type | Description |
|---|---|---|
id | string | The job's UUID — the job_id you got back from POST /api/clips. |
status | string | Where the job is in the pipeline. See Job status below. |
priority | boolean | true if this was a reserved (priority) job, false for a best-effort one. Set from the key that submitted it. |
fps | integer | null | Recording framerate. null when you didn't specify one at submit — the renderer applies its default. |
resolution | integer | Render resolution. |
clip_id | string | null | The clip this job produced, once it succeeds. null until then (and on a failed job). Look it up via GET /api/clips/:id. |
error_code | string | null | Why the job failed. null unless status is retrying or error. Same values as the webhook — see Error codes. |
created_at | string | ISO 8601 timestamp of when the job was submitted. |
finished_at | string | null | ISO 8601 timestamp of when the job reached a terminal state (done or error). null while it's still in flight or waiting to retry. |
payload | object | The 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:
| Status | Meaning |
|---|---|
pending | Queued, waiting for a render slot. It hasn't started yet. |
prefetch | Claimed by a render host, which is downloading the demo before rendering. |
render | Being rendered right now inside CS2. |
done | Rendered successfully. clip_id points to the finished clip. |
retrying | The 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. |
error | The 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 (
doneorerror) 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
retryingjob can also be resubmitted — doing so just skips the wait until its next automatic retry. - A job that is still in flight (
pending,prefetch, orrender) cannot be resubmitted, since a render host may be working on it. This returns409. Wait for it to finish, then resubmit if you still need to.
| Status | Response |
|---|---|
| Job reset and re-queued | 200 with { "job_id": "..." } |
| No job with that id under your account | 404 |
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 ajob_idand want to run that exact job again, unchanged. No body, no idempotency key, keeps the original webhook.POST /api/clipswithforce: true— the path when you want to redo a job and change something about it (a newwebhook_url, for instance), or when you track jobs by your ownidempotency_keyrather than byjob_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 (
doneorerror) with awebhook_urlset. A job submitted without awebhook_urlhas nothing to resend. - A job still in flight (
pending/prefetch/render) has no settled outcome to resend, and returns409.
| Status | Response |
|---|---|
| Webhook queued for delivery | 200 with { "delivery_id": "..." } |
| No job with that id under your account | 404 |
Job is still in flight (pending / prefetch / render) | 409 |
| Job has no outcome webhook to resend | 409 |