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
| Method | POST |
| Auth | Authorization: Bearer YOUR_API_KEY (see Authentication) |
| Content-Type | application/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:
| Field | Type | Required | Description |
|---|---|---|---|
demo_url | string | yes | A publicly reachable URL to the CS2 demo (.dem) file to render. |
steam64_id | string | yes | The 64-bit Steam ID of the player whose point of view should be captured. |
round | integer | yes | The round number to capture. Must be a positive integer (1 or greater). |
fps | integer | no | Recording framerate. Either 30 or 60. Defaults to 30 when omitted. |
resolution | integer | no | Render resolution. Either 1080 or 1440. Defaults to 1080 when omitted. Together with fps it determines the metered rate. |
commands | object | no | Per-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:
| Command | Values | Default | Description |
|---|---|---|---|
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.
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
| Status | Body | Cause |
|---|---|---|
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.
Recommended workflow
- Resolve the demo URL, the player's
steam64_id, and theroundyou want to capture. POST /api/clipswith those three fields and your API key.- Store the returned
job_idagainst the match/player in your own system. - Surface the finished clip to your users — embed it via iframe or download the MP4 — once rendering completes.