Skip to main content

Submitting Render Jobs

A render job tells dinkem.gg which moment to turn into a clip: a demo, the player to follow, and the round to capture. You submit one with a single POST request; we queue it and render the clip asynchronously.


Endpoint

POST https://dinkem.gg/api/clips
MethodPOST
AuthAuthorization: Bearer YOUR_API_KEY (see Authentication)
Content-Typeapplication/json

The key you authenticate with selects the job type: your metered key submits best-effort renders (metered per rendered hour), your reserved key submits priority renders covered by your provisioned dinks. The request body is identical for both.


Request body

The body is a JSON object with the following fields:

FieldTypeRequiredDescription
demo_urlstringyesA publicly reachable URL to the CS2 demo (.dem) file to render.
steam64_idstringyesThe 64-bit Steam ID of the player whose point of view should be captured.
roundintegeryesThe round number to capture. Must be a positive integer (1 or greater).
fpsintegernoRecording framerate. Either 30 or 60. Defaults to 30 when omitted.
resolutionintegernoRender resolution. Either 1080 or 1440. Defaults to 1080 when omitted. Together with fps it determines the metered rate.
commandsobjectnoPer-job CS2 console command overrides. Each key is a command name, each value is a string. See Supported commands below.

Example

{
"demo_url": "https://cdn.example.com/matches/abc123.dem",
"steam64_id": "76561198000000000",
"round": 5,
"fps": 30,
"resolution": 1080,
"commands": {
"spec_show_xray": "1"
}
}

Supported commands

The commands object accepts the following keys:

CommandValuesDefaultDescription
spec_show_xray"0", "1""0"Show player outlines through walls.
cl_draw_only_deathnotices"0", "1""1"When "1", hides the HUD except for kill feed. Set to "0" to show the full HUD.

Only the commands listed above are accepted. Unknown command names or invalid values return a 400.

Field types are validated strictly

demo_url and steam64_id must be JSON strings and round must be a JSON integer. Sending a number where a string is expected (or vice versa), or a non-integer round, returns a 400. Wrap steam64_id in quotes — a bare 17-digit number can lose precision in some JSON encoders. When fps is present it must be exactly 30 or 60, and when resolution is present it must be exactly 1080 or 1440.


http://replay392.valve.net/730/003825165981261496349_0964821099.dem.bz2 76561198077094129 --rounds 16

Examples

cURL

curl -X POST https://dinkem.gg/api/clips \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"demo_url": "http://replay392.valve.net/730/003825165981261496349_0964821099.dem.bz2",
"steam64_id": "76561198077094129",
"round": 16,
"fps": 30
}'

JavaScript / Node.js

const res = await fetch('https://dinkem.gg/api/clips', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DINKEM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
demo_url: 'https://cdn.example.com/matches/abc123.dem',
steam64_id: '76561198000000000',
round: 5,
fps: 30,
}),
});

if (!res.ok) {
throw new Error(`Render job failed: ${res.status} ${await res.text()}`);
}

const { job_id } = await res.json();
console.log('Queued render job', job_id);

Python

import os
import requests

res = requests.post(
"https://dinkem.gg/api/clips",
headers={"Authorization": f"Bearer {os.environ['DINKEM_API_KEY']}"},
json={
"demo_url": "https://cdn.example.com/matches/abc123.dem",
"steam64_id": "76561198000000000",
"round": 5,
"fps": 30,
},
timeout=30,
)
res.raise_for_status()

job_id = res.json()["job_id"]
print("Queued render job", job_id)

Response

On success the API returns HTTP 201 with the ID of the queued job:

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

The job_id is a UUID identifying your render job. Store it so you can correlate the job with the clip it produces.

Submitting a job only queues it — rendering happens asynchronously. A 201 means the job was accepted, not that the clip is ready.


Errors

StatusBodyCause
400{ "error": "demo_url (string), steam64_id (string) and round (positive integer) are required" }A field is missing, has the wrong type, or round is not a positive integer.
400{ "error": "fps must be 30 or 60" }fps was provided but is not 30 or 60.
400{ "error": "resolution must be 1080 or 1440" }resolution was provided but is not 1080 or 1440.
400{ "error": "unknown command: ..." }commands contains a key that is not in the supported commands list.
400{ "error": "invalid value for ...: must be one of ..." }A command value is not one of the allowed values for that command.
401{ "error": "Missing or invalid API key" }The Authorization header is missing or malformed. See Authentication.
401{ "error": "Invalid API key" }The key does not match an active account.
403{ "error": "No reserved capacity provisioned" }The reserved key was used but the account has no provisioned dinks.

A non-201 response means the job was not queued. Fix the reported issue and resubmit.


  1. Resolve the demo URL, the player's steam64_id, and the round you want to capture.
  2. POST /api/clips with those three fields and your API key.
  3. Store the returned job_id against the match/player in your own system.
  4. Surface the finished clip to your users — embed it via iframe or download the MP4 — once rendering completes.