API v1

Kineto API reference

Realtime video editing, built for live streams. Start a session, connect your camera, and steer the result with a text prompt, a reference photo, or both. All requests are JSON over HTTPS and authenticated with a secret API key.

text
https://dev.paykoda.space/api/public/v1

Quickstart

Create a key in the dashboard, export it, then make your first call.

bash
export KINETO_API_KEY="kn_live_..."

curl -X POST https://dev.paykoda.space/api/public/v1/realtime/sessions \
  -H "Authorization: Bearer $KINETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"kineto-realtime-720p"}'

Authentication

Send your secret key as a bearer token. Keys are server-side only — never ship one to a browser or mobile app.

bash
curl https://dev.paykoda.space/api/public/v1/account \
  -H "Authorization: Bearer $KINETO_API_KEY"

A revoked or unknown key returns 401 authentication_error. For untrusted clients, mint an ephemeral realtime session instead of sharing the key.

POST /realtime/sessions

Mints a short-lived session secret for a realtime stream, with the style prompt and reference photo you want the live video edited to match. Charged 25 credits per session.

Parameters
Request parameters
modelstring, requiredkineto-realtime-720p or kineto-realtime-1080p
promptstring, optionalStyle prompt applied to the live video
reference_image_urlstring, optionalPublicly reachable photo the stream is edited to match (character, outfit, scene). Max 8 MB
enhance_promptboolean, optionalAuto-expand the prompt. Defaults to true
ttl_secondsinteger, optionalSession lifetime, 60–1800. Defaults to 600
bash
curl -X POST https://dev.paykoda.space/api/public/v1/realtime/sessions \
  -H "Authorization: Bearer $KINETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kineto-realtime-1080p",
    "prompt": "turn me into this character",
    "reference_image_url": "https://cdn.example.com/character.jpg",
    "ttl_seconds": 900
  }'
json
{
  "id": "3f0c...",
  "object": "realtime.session",
  "model": "kineto-realtime-1080p",
  "prompt": "turn me into this character",
  "reference_image_url": "https://cdn.example.com/character.jpg",
  "client_secret": { "value": "kns_...", "expires_at": "2026-09-22T13:20:00.000Z" },
  "websocket_url": "wss://dev.paykoda.space/api/public/v1/realtime/stream?token=kns_...",
  "expires_at": "2026-09-22T13:20:00.000Z",
  "credits_charged": 25,
  "credits_remaining": 4975
}

Hand websocket_url (or just client_secret.value) to the browser that owns the camera. The session secret is single-purpose, expires with ttl_seconds, and never exposes your secret API key to the client. The prompt and reference photo you set here are applied the moment the stream opens.

Streaming from the browser

Connect to the session socket, publish the camera, and render the edited stream. Video travels peer-to-peer, so latency stays low and your server carries only the control channel.

Install the media client with npm i livekit-client. The socket is a control channel: you send a join message, receive the room credentials, then publish and subscribe. Frames are never uploaded to the API host.

bash
# 1. your server mints the session
SESSION=$(curl -s -X POST https://dev.paykoda.space/api/public/v1/realtime/sessions \
  -H "Authorization: Bearer $KINETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"kineto-realtime-720p","prompt":"anime style portrait"}')

# 2. pass session.websocket_url to the browser (see the Node.js tab)
echo "$SESSION" | jq -r .websocket_url
Parameters
Request parameters
livekit_joinclient → serverStarts negotiation. Send it as soon as the socket opens
promptclient → serverChanges the style mid-stream: { prompt, enhance_prompt? }
set_imageclient → serverSwaps the reference photo: { image_data (base64), prompt?, enhance_prompt? }
livekit_room_infoserver → clientMedia credentials: { livekit_url, token, room_name }
prompt_ack / set_image_ackserver → clientConfirms a style change
generation_started / generation_tick / generation_endedserver → clientStream lifecycle and billed seconds
errorserver → client{ code, error } — see the close codes below

Failures arrive as an error message followed by a close code: 4001 authentication_error (missing or unknown session token), 4003 session_expired or session_closed, 4011 upstream_error (streaming backend unavailable). A reference photo that cannot be downloaded sends a non-fatal reference_image_error and the stream continues with the prompt only.

POST /transforms

Transforms a video or an image. Image jobs return status succeeded with the finished output_url in the same response; video jobs return 202 with a job id to poll.

Parameters
Request parameters
modelstring, requiredkineto-video-v1 or kineto-image-v1
promptstring, requiredWhat the output should look like
input_urlstring, requiredPublicly reachable source video or image URL
webhook_urlstring, optionalCalled when the job reaches a final status
bash
curl -X POST https://dev.paykoda.space/api/public/v1/transforms \
  -H "Authorization: Bearer $KINETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kineto-video-v1",
    "prompt": "cyberpunk neon, rain-slicked streets",
    "input_url": "https://cdn.example.com/clip.mp4"
  }'
json
{
  "id": "job_8c21...",
  "object": "transform.job",
  "model": "kineto-video-v1",
  "kind": "video",
  "status": "processing",
  "output_url": null,
  "credits_charged": 120,
  "credits_remaining": 4855
}

If the transformation backend rejects a job, the call returns 502 upstream_error and your credits are refunded automatically.

GET /transforms/{id}

Fetches the current status of a job. Poll every few seconds until status is succeeded or failed.

bash
curl https://dev.paykoda.space/api/public/v1/transforms/job_8c21 \
  -H "Authorization: Bearer $KINETO_API_KEY"

GET /account

Returns the credit balance and metadata for the key making the request. Free of charge.

bash
curl https://dev.paykoda.space/api/public/v1/account -H "Authorization: Bearer $KINETO_API_KEY"
json
{
  "object": "account",
  "credits_remaining": 4855,
  "key": { "name": "Production server", "environment": "live", "masked": "kn_live_a1b2...9xyz" }
}

Models

Credit price is fixed per model.

kineto-realtime-720p

Live video-to-video restyling at 720p, sub-100ms frame latency.

25 credits per session minute
kineto-realtime-1080p

Live video-to-video restyling at 1080p for desktop capture.

45 credits per session minute
kineto-video-v1

Asynchronous prompt-driven transformation of an uploaded clip.

120 credits per job
kineto-image-v1

Single-frame restyling and editing from a prompt.

10 credits per job

Errors

Errors use standard HTTP statuses with a machine-readable type.

Parameters
Request parameters
400 invalid_request_errorMissing or malformed parameters
401 authentication_errorMissing, unknown or revoked API key
402 insufficient_creditsBalance too low for the requested model
404 not_foundThe job id does not belong to your account
502 upstream_errorTransformation backend unavailable; credits refunded
json
{
  "error": {
    "type": "insufficient_credits",
    "message": "Not enough credits for this job."
  }
}