--- url: /api.md --- # Quickstart The Klik Engine `/v1` API is the public, API-key-authenticated surface for headless clients: autonomous "creator brains", CI pipelines, batch generators, or any program that wants to drive game generation without a browser session. It is a **general creation contract**. On top of the free-text `prompt`, a caller composes exactly the guidance it needs through layered fields (`instructions`, `context`, `skills`, `settings`). Nothing is specific to any one client - a persona-driven short-game brain and a CI regression harness use the same endpoints. ## Base URL | Environment | Base URL | |---|---| | Production | `https://ai.klikg.com` | | Edge (internal dev) | `https://edgeai.klikg.com` | All routes below are relative to the base URL. ## 1. Get an API key Create a key in the lab under the **API Keys** tab: [ai.klikg.com/lab](https://ai.klikg.com/lab). The full `sk-...` secret is shown **exactly once** at creation time. See [Authentication & keys](/api/authentication) for limits and management. ## 2. Create a project ```bash curl -X POST https://ai.klikg.com/v1/projects \ -H "Authorization: Bearer sk-..." \ -H "Content-Type: application/json" \ -d '{ "name": "My Game", "template": "blank" }' ``` The response contains `data._id` - that is your `projectId`. ## 3. Submit a generation job ```bash curl -X POST https://ai.klikg.com/v1/generate \ -H "Authorization: Bearer sk-..." \ -H "Content-Type: application/json" \ -d '{ "projectId": "", "prompt": "Build a one-button endless runner where you dodge falling blocks." }' ``` Response: `{ "jobId": "...", "status": "queued" }`. ::: tip Cold starts The first job on an idle project cold-starts its engine container, which can take up to ~2 minutes. During that window the endpoint returns `503` with a retry hint - **retry every ~30 seconds** until it accepts. ::: Only `projectId` and `prompt` are required. The [creation contract](/api/creation-contract) documents the optional `instructions`, `context`, `skills`, and `settings` fields that give you precise control over the output. ## 4. Wait for completion Poll status (does not consume quota): ```bash curl https://ai.klikg.com/v1/generate//status?projectId= \ -H "Authorization: Bearer sk-..." ``` ...or stream progress as Server-Sent Events from `GET /v1/generate//events`. Terminal statuses are `completed`, `failed`, and `cancelled`. ## 5. Download the game ```bash curl -L -o game.zip \ "https://ai.klikg.com/v1/generate//files?projectId=" \ -H "Authorization: Bearer sk-..." ``` The ZIP contains the files the job wrote - a complete, runnable web game. ## Next steps * [Endpoints](/api/endpoints) - full request/response reference * [The creation contract](/api/creation-contract) - `instructions`, `context`, `skills`, `settings` * [Examples](/api/examples) - complete curl and Node.js flows * [Errors & rate limits](/api/errors) - every status code and how to handle it --- --- url: /api/authentication.md --- # Authentication & keys Every `/v1` request carries a per-user secret key (`sk-...`) via either header: ``` Authorization: Bearer sk-... ``` or ``` X-API-Key: sk-... ``` ## Creating keys Create and manage keys in the lab under the **API Keys** tab: [ai.klikg.com/lab](https://ai.klikg.com/lab). * The full secret is shown **exactly once** at creation time. Only a masked form (`sk-ab****cdef`) is retrievable afterwards - if you lose a secret, revoke the key and create a new one. * Each user can hold up to 20 non-revoked keys. * Keys can be renamed, disabled/re-enabled, and permanently revoked from the same tab. ## Per-key limits Each key has four editable limits. Blank means unlimited (still subject to the user's TIK balance, which is enforced separately). | Limit | Enforced when | |---|---| | Jobs / day | On job submission. Resets at 00:00 UTC. | | Jobs / month | On job submission. Resets on the 1st of each month (UTC). | | Max concurrent jobs | On job submission, against currently running jobs for the key. | | TIK / month | On job submission, against TIK spent through this key this month. | A submission over a limit is rejected with `429`: ```json { "error": "Rate limit exceeded", "reason": "limit_exceeded", "limit": "jobsPerDay" } ``` Only **job submissions** (`POST /v1/generate`) count against quotas. Status polls, event streams, and file downloads never consume quota, and neither do submissions rejected during a cold start (`503`). ## Key lifecycle | State | Behavior | |---|---| | `active` | Works normally. | | `disabled` | All requests rejected with `401` (`reason: "disabled"`). Reversible from the lab. | | `revoked` | All requests rejected with `401` (`reason: "revoked"`). Permanent. | ## Security notes * Treat keys like passwords: server-side only, never in client-side code or public repositories. * The platform stores only a SHA-256 hash of each secret. * Usage (jobs today / this month, TIK spent) is visible per key in the lab, so one key per integration makes attribution and revocation clean. --- --- url: /api/endpoints.md --- # Endpoints All endpoints are relative to the base URL (`https://ai.klikg.com`) and require [authentication](/api/authentication). ## `POST /v1/projects` Create a project owned by the key's user. An autonomous client typically creates one project per game. Request body: ```json { "name": "My Game", "template": "blank", "description": "optional" } ``` Response `201`: ```json { "success": true, "data": { "_id": "", "name": "My Game" } } ``` `data._id` is the `projectId` used by every other endpoint. ## `POST /v1/generate` Submit a generation job. Cold-starts the project's engine container if it is not already running - a cold start can take up to ~2 minutes, during which the endpoint returns `503` with a retry hint (retry every ~30 s). Request body (only `projectId` and `prompt` are required): ```json { "projectId": "<24-hex project id>", "prompt": "Build a one-button endless runner where you dodge falling blocks.", "instructions": "Persistent direction: bold flat-color art, punchy game feel, 30-60s shorts.", "context": [ { "name": "research", "content": "Endless runners peak retention with a 3-second failure-restart loop..." } ], "skills": [ { "key": "one-button-runner", "title": "One-button runner core loop", "prompt": "endless runner, tap to jump", "mechanics": ["gravity", "obstacle spawn", "score on distance"], "engine": "phaser", "files": [ { "path": "src/scenes/GameScene.js", "content": "// proven code ..." } ] } ], "settings": { "gameType": "klik-short", "model": "openrouter/claude-fable-5", "reasoningLevel": "medium", "dimensionMode": "2d", "aiImages": true, "aiAudio": true, "visualQaActive": true } } ``` Every optional field is documented in [The creation contract](/api/creation-contract). Response `200`: ```json { "jobId": "", "projectId": "", "status": "queued", "sessionId": "" } ``` This is the only endpoint that counts against [per-key quotas](/api/authentication#per-key-limits). ## `GET /v1/generate/:jobId/status` Poll job status. The response mirrors the engine's job record (`status`, progress, and so on). Statuses progress through `queued` / `running` to a terminal `completed`, `failed`, or `cancelled`. Polls consume no quota. ## `GET /v1/generate/:jobId/events` Server-Sent Events stream of the job's progress - the same event stream the IDE consumes (assistant text, tool calls, build results, completion). Reconnect-friendly; polling `status` is the simpler alternative. ## `GET /v1/generate/:jobId/files` Download a ZIP of the files written by the job. Available once the job is `completed` or `failed`. ## `DELETE /v1/generate/:jobId` Cancel a running job. ::: warning Pass `projectId` on follow-up calls Follow-up routes (`status`, `events`, `files`, `DELETE`) resolve the job's container from an in-memory route table recorded at submission. After a gateway restart that table is empty - always pass `?projectId=` on these calls so the gateway can re-resolve the container. It is harmless when not needed and makes clients restart-proof. ::: --- --- url: /api/creation-contract.md --- # The creation contract `POST /v1/generate` accepts a layered set of fields. Each layer has a different lifetime and a different job, so a client can compose exactly the guidance it needs - from a one-line prompt to a fully-directed, persona-driven, research-backed brief with proven code attached. | Field | Persisted? | Purpose | |---|---|---| | `prompt` | no | The per-job brief: what to build or change right now. | | `instructions` | yes - project `AGENTS.md` | Persistent direction, persona, or style guide for the whole project. | | `context` | no | Per-job blocks injected verbatim - the accuracy lever. | | `skills` | yes - `.klik/skills/` | Reusable proven code, stored and force-injected for this job. | | `settings` | sticky | Engine options (game type, model, reasoning level, ...). | ## `prompt` (required) Free text describing what to build or change in this job. On a fresh project it is the game brief; on later jobs it is the change request ("make the obstacles faster, add a combo counter"). ## `instructions` - persistent direction A string persisted to the project's `AGENTS.md` file. Every future job on the project inherits it as `` in the system prompt - send it once, and all follow-up jobs stay on-style. * Re-sending `instructions` **replaces** the previous value. * Omitting it leaves the existing value untouched. Use it for anything that should hold across the project's lifetime: a creator persona and voice, an art direction, hard rules ("always show a restart button within 1 second of death"), disclosure requirements, or brand constraints. ```json { "instructions": "You are DreamCast, an autonomous creator. Bold flat-color art, punchy game feel, always a 30-60 second short. Be transparent that games are AI-made." } ``` ## `context` - per-job accuracy blocks An array of named blocks injected **verbatim** into the system prompt as ``, visible only for this job. This is the precision lever: research notes, design documents, reference mechanics, playtest feedback, level data - anything the model should read before building. ```json { "context": [ { "name": "research", "content": "Top-performing runners restart within 3 seconds of failure..." }, { "name": "playtest-feedback", "content": "Players said the jump felt floaty; tighten gravity." } ] } ``` Because `context` is not persisted, iterating clients can send fresh findings with each job without accumulating stale guidance. ## `skills` - reusable proven code An array of skill objects. Skills serve two purposes at once: 1. **Stored** in the project's skill store (`.klik/skills/`), where they become available for similarity-based reuse in later jobs. 2. **Force-injected** into this job's prompt as ``, so the model treats the attached code as a known-good starting point. ```json { "skills": [ { "key": "one-button-runner", "title": "One-button runner core loop", "prompt": "endless runner, tap to jump", "mechanics": ["gravity", "obstacle spawn", "score on distance"], "engine": "phaser", "files": [ { "path": "src/scenes/GameScene.js", "content": "// proven code ..." } ] } ] } ``` | Skill field | Required | Meaning | |---|---|---| | `key` | yes | Stable identifier; re-sending the same key updates the stored skill. | | `title` | yes | Human-readable name. | | `prompt` | no | The kind of request this skill solves (used for similarity matching). | | `mechanics` | no | Mechanic tags (`"gravity"`, `"obstacle spawn"`, ...). | | `engine` | no | Target engine, e.g. `phaser`, `three`, `pixi`. | | `files` | yes to store | The proven code itself. Skills without `files` are injected for this job but not stored. | ## `settings` - engine options Sticky per-project engine options. Send only what you want to change; values persist across jobs until changed again. | Setting | Values | Meaning | |---|---|---| | `gameType` | `klik-short`, `platform` | `klik-short` targets 15-60s one-mechanic portrait games; `platform` removes the short-game framing. | | `model` | e.g. `openrouter/claude-fable-5` | The LLM used for generation. | | `reasoningLevel` | `low`, `medium`, `high` | Reasoning effort; higher is slower and more expensive but better on complex briefs. | | `dimensionMode` | `2d`, `3d` | `3d` sets up Three.js and 3D editor support. | | `aiImages` | `true`, `false` | Generate sprite/background art with AI (billed in TIK). `false` uses placeholders. | | `aiAudio` | `true`, `false` | Generate sound effects and music with AI (billed in TIK). | | `visualQaActive` | `true`, `false` | Run the visual QA pass after generation. | | `chatMode` | `agent`, `plan` | `agent` builds; `plan` produces a plan/analysis without writing game code. | ## How the layers combine For a given job the engine assembles, in order: the project's persistent `instructions` (as ``), the job's `context` blocks (as ``), the injected `skills` (as ``), and finally your `prompt`. A typical autonomous-creator loop: 1. First job: send `instructions` (persona), `context` (research), `skills` (proven mechanics), `settings`, and the game brief `prompt`. 2. Follow-up jobs: send only `prompt` (and fresh `context` such as playtest feedback) - the persona and skills are already in place. --- --- url: /api/errors.md --- # Errors & rate limits ## Status codes | Status | Meaning | What to do | |---|---|---| | `400` | Missing/invalid `projectId` or `prompt`. | Fix the request; do not retry as-is. | | `401` | Missing, invalid, revoked, or disabled key (`reason` says which). | Check the key in the [lab](https://ai.klikg.com/lab); create a new one if revoked. | | `403` | The key's user has no access to the project. | Use a `projectId` created by the same user as the key. | | `429` | A per-key limit was hit. | Back off; see below. | | `503` | Engine container still starting, or key validation temporarily unavailable. | Retry - see cold starts below. | Error bodies are JSON with an `error` message and, where relevant, a machine-readable `reason`. ## `429` - rate limits ```json { "error": "Rate limit exceeded", "reason": "limit_exceeded", "limit": "jobsPerDay" } ``` `limit` names the exceeded limit: | `limit` | Resets | |---|---| | `jobsPerDay` | 00:00 UTC | | `jobsPerMonth` | 1st of the month, UTC | | `maxConcurrentJobs` | As soon as one of the key's running jobs finishes | | `tikPerMonth` | 1st of the month, UTC | Limits are edited per key in the lab. Only job submissions count against quotas - status polls, event streams, and downloads are free, and a `503` rejection does not consume quota. ## `503` - cold starts The first job on an idle project boots its engine container, which can take up to ~2 minutes: ```json { "error": "Engine container is starting", "retryAfterSeconds": 30 } ``` Recommended client behavior: 1. On `503` from `POST /v1/generate`, wait `retryAfterSeconds` (default 30 s) and resubmit the same request. 2. Keep retrying up to an overall deadline of ~8 minutes. 3. Treat a `200` with a `jobId` as the single successful submission - rejected `503` attempts never created a job. ## TIK balance Generation spends TIK from the key owner's account (LLM usage, and AI images/audio when enabled). If the balance runs out mid-job, the job fails with a TIK error visible in the status record. The optional per-key monthly TIK budget caps how much a single key can spend. --- --- url: /api/examples.md --- # Examples ## curl - end-to-end flow ```bash BASE="https://ai.klikg.com" KEY="sk-..." # 1. Create a project PROJECT_ID=$(curl -s -X POST "$BASE/v1/projects" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Runner Demo", "template": "blank" }' | jq -r '.data._id') # 2. Submit a job (retry on 503 cold start) until JOB=$(curl -s -f -X POST "$BASE/v1/generate" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d "{ \"projectId\": \"$PROJECT_ID\", \"prompt\": \"Build a one-button endless runner where you dodge falling blocks.\", \"settings\": { \"gameType\": \"klik-short\" } }"); do echo "engine starting, retrying in 30s..."; sleep 30 done JOB_ID=$(echo "$JOB" | jq -r '.jobId') # 3. Poll until terminal while :; do STATUS=$(curl -s "$BASE/v1/generate/$JOB_ID/status?projectId=$PROJECT_ID" \ -H "Authorization: Bearer $KEY" | jq -r '.status') echo "status: $STATUS" case "$STATUS" in completed|failed|cancelled) break;; esac sleep 10 done # 4. Download the game curl -sL -o game.zip \ "$BASE/v1/generate/$JOB_ID/files?projectId=$PROJECT_ID" \ -H "Authorization: Bearer $KEY" ``` ## Node.js - autonomous creator loop A complete script using only built-in `fetch` (Node 18+). It sends the full creation contract on the first job, then a follow-up job that inherits the persisted instructions. ```js const BASE = process.env.KLIK_BASE ?? 'https://ai.klikg.com'; const KEY = process.env.KLIK_API_KEY; // sk-... const headers = { 'Authorization': `Bearer ${KEY}`, 'Content-Type': 'application/json', }; async function api(method, path, body) { const res = await fetch(`${BASE}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); if (!res.ok) { const err = new Error(`${method} ${path} -> ${res.status}`); err.status = res.status; err.body = await res.json().catch(() => null); throw err; } return res.json(); } // Submit with 503 cold-start retries (up to 8 minutes). async function submitJob(body) { const deadline = Date.now() + 8 * 60_000; for (;;) { try { return await api('POST', '/v1/generate', body); } catch (err) { if (err.status !== 503 || Date.now() > deadline) throw err; const wait = (err.body?.retryAfterSeconds ?? 30) * 1000; console.log(`engine starting, retrying in ${wait / 1000}s...`); await new Promise(r => setTimeout(r, wait)); } } } async function waitForJob(jobId, projectId) { for (;;) { const job = await api( 'GET', `/v1/generate/${jobId}/status?projectId=${projectId}` ); console.log(`status: ${job.status}`); if (['completed', 'failed', 'cancelled'].includes(job.status)) return job; await new Promise(r => setTimeout(r, 10_000)); } } // 1. Project const project = await api('POST', '/v1/projects', { name: 'Runner Demo', template: 'blank', }); const projectId = project.data._id; // 2. First job: full creation contract const first = await submitJob({ projectId, prompt: 'Build a one-button endless runner where you dodge falling blocks.', instructions: 'Bold flat-color art, punchy game feel, always a 30-60 second short. ' + 'Be transparent that games are AI-made.', context: [ { name: 'research', content: 'Top-performing runners restart within 3 seconds of failure. ' + 'Difficulty should ramp every 10 seconds.', }, ], settings: { gameType: 'klik-short', reasoningLevel: 'medium' }, }); await waitForJob(first.jobId, projectId); // 3. Follow-up job: instructions persist, so only the change request is needed const second = await submitJob({ projectId, prompt: 'Tighten the jump gravity and add a combo counter for near-misses.', context: [ { name: 'playtest-feedback', content: 'Players said the jump felt floaty.' }, ], }); await waitForJob(second.jobId, projectId); // 4. Download the ZIP const zipRes = await fetch( `${BASE}/v1/generate/${second.jobId}/files?projectId=${projectId}`, { headers } ); const fs = await import('node:fs/promises'); await fs.writeFile('game.zip', Buffer.from(await zipRes.arrayBuffer())); console.log('saved game.zip'); ``` ## Streaming progress (SSE) Instead of polling, consume the live event stream: ```js const res = await fetch( `${BASE}/v1/generate/${jobId}/events?projectId=${projectId}`, { headers: { Authorization: `Bearer ${KEY}` } } ); const reader = res.body.getReader(); const decoder = new TextDecoder(); for (;;) { const { done, value } = await reader.read(); if (done) break; process.stdout.write(decoder.decode(value)); } ``` Events include assistant text, tool calls, build results, and the final completion event. --- --- url: /engine.md --- # Klik Engine overview Klik Engine is an AI game creation environment at [ai.klikg.com](https://ai.klikg.com). You describe a game - in the browser IDE or through the [API](/api/) - and an agentic generation engine writes the code, generates art and audio, builds the game, tests it, and hands you a playable result. ## Two ways in | Surface | For | Entry point | |---|---|---| | **The Lab + IDE** | Creators working interactively | [ai.klikg.com/lab](https://ai.klikg.com/lab) - chat-driven IDE with live preview, visual scene editor, and publishing | | **The `/v1` API** | Programs - autonomous creator brains, CI pipelines, batch generators | [API Quickstart](/api/) - headless project creation, job submission, progress streaming, ZIP download | Both surfaces drive the same backend generation engine, so a project started via the API can be opened in the IDE and vice versa. ## What happens during a generation job Every job - whether from the IDE chat or `POST /v1/generate` - runs through the same pipeline: 1. **Prompt assembly.** The engine composes your prompt with the project's persistent conventions (`AGENTS.md`), any per-job context, relevant proven skills, and engine rules for the selected game type. 2. **Agentic code generation.** The model works in rounds: it writes and edits files, requests sprites/backgrounds/audio, runs builds, and reacts to errors, using 30+ backend tools. 3. **Quality pipeline.** Deterministic passes run before you see the result: an AST-based code sanitizer, structural audits (input handlers, colliders, win/lose state), an asset integration pass, a style-coherence audit, and automated playtest probes (HUD present, FPS, input responsiveness). Findings feed an auto-fix loop. 4. **Result.** The game is served in the live preview (IDE) and its files are downloadable as a ZIP (API). Each job also records an evaluation record that improves future generations through few-shot retrieval. ## Projects A project is one game: its code, assets, chat history, skills, and settings. Project metadata lives in the Klik platform; files live in the project workspace. Persistent state that travels with a project includes: | Item | Where | Set by | |---|---|---| | Conventions / persona | `AGENTS.md` | IDE edits or the API `instructions` field | | Proven skills | `.klik/skills/` | Auto-harvested from successful runs, or the API `skills` field | | Art style descriptor | `.klik/style.json` | The engine, first time a style is established | | Engine settings | project settings | IDE selectors or the API `settings` field | ## Skills - the engine's memory When a generation run succeeds, the engine harvests the working mechanics into a **skill**: a named bundle of proven code plus metadata (which kind of prompt it solves, which mechanics, which engine). On later jobs, similar skills are retrieved and injected so the model starts from code that is known to work. API clients can also [supply skills directly](/api/creation-contract#skills-reusable-proven-code). ## Billing Generation spends **TIK**, the platform currency, from the project owner's account - LLM usage plus AI images and audio when enabled. API keys can carry a [monthly TIK budget](/api/authentication#per-key-limits) to cap what a single integration can spend. ## Learn more * [Game types & settings](/engine/game-types) - what the engine options do * [Analytics SDK](/engine/analytics) - player analytics inside every game * [API reference](/api/) - drive all of this programmatically --- --- url: /engine/game-types.md --- # Game types & settings These options steer every generation job. In the IDE they are dropdowns and toggles; through the API they are the [`settings` object](/api/creation-contract#settings-engine-options). They are **sticky** per project - set once, they hold until changed. ## Game type | Value | What it means | |---|---| | `klik-short` | A "Klik short": one core mechanic, roughly 15-60 seconds of gameplay, portrait 480x720, instant restart. The engine enforces short-game rules (single-tap-friendly input, immediate fail-restart loop, visible score). Best for feed-style distribution. | | `platform` | No short-game framing - any scope, any format. The engine still applies its quality pipeline but does not constrain length or mechanics. | ## Dimension mode | Value | What it means | |---|---| | `2d` (default) | 2D games - Phaser is the default framework; PixiJS and plain Canvas also supported. The visual editor uses the 2D canvas. | | `3d` | Three.js + Vite setup, 3D-aware prompts, and the 3D editor viewport. | ## Model and reasoning | Setting | Notes | |---|---| | `model` | Which LLM generates the game. Better models cost more TIK per job. | | `reasoningLevel` | `low`, `medium`, or `high`. Higher levels spend more thinking time - better on complex briefs, slower and more expensive on simple ones. | ## AI assets | Setting | On (`true`) | Off (`false`) | |---|---|---| | `aiImages` | Sprites and backgrounds are AI-generated in the project's art style (billed in TIK). | Shape-aware placeholder graphics drawn from the project palette. | | `aiAudio` | Sound effects and music are AI-generated (billed in TIK). | Silent placeholders. | Placeholders are useful for cheap iteration on mechanics before spending TIK on final art. ## Quality and modes | Setting | What it does | |---|---| | `visualQaActive` | Runs the visual QA pass after generation - the engine screenshots the game and verifies sizing, positioning, and visual consistency, fixing issues it finds. | | `chatMode` | `agent` (default) builds the game. `plan` produces analysis or a build plan without writing game code - useful for asking design questions or reviewing analytics before committing to changes. | ## Art style consistency The first time a project establishes an art direction, the engine persists a style descriptor (`.klik/style.json`: art style, palette, mood, era, lighting). Every subsequent asset request automatically inherits it, and a post-generation audit flags palette outliers - so a project keeps a coherent look across many jobs without repeating style guidance in every prompt. --- --- url: /engine/analytics.md --- # Analytics SDK Every game published from Klik Engine ships pre-wired with the Klik analytics SDK. Players' sessions, custom events, funnels, and A/B tests flow into a per-game dashboard without any manual setup - the engine writes the tracking calls during generation and registration happens automatically at publish time. ## What you get out of the box * **Sessions** - starts, ends, duration, and outcomes, tracked automatically. * **Custom events** - the generation engine defines and tracks events that fit the game (level completed, power-up picked, and so on). * **Funnels** - multi-step progression tracking. * **End-of-game flow** - `klik.endGame()` sequences the outcome event, leaderboard submission, reward earning, and the leaderboard overlay in a single call. ## The `klik.*` API The SDK exposes a global `klik` object inside every game: | Call | Purpose | |---|---| | `klik.ready(cb)` | Runs `cb` once the SDK is initialized (required before reading A/B variants). | | `klik.define(name, schema)` | Declares a typed custom event. | | `klik.track(name, props)` | Records an event occurrence. | | `klik.funnel(id).step(n, eventName)` | Declares funnel steps. | | `klik.endGame({ outcome, score, ... }, cb)` | The single call to make at win/lose - outcome, leaderboard, rewards, overlay. | | `klik.debug()` | Returns SDK state (`gameId`, endpoint, buffered events, defined events) for self-diagnosis. | | `klik.health()` | Pings ingestion and resolves `{ ok, ms, status }`. | Game identity (`gameId`, analytics key, endpoint) is injected at runtime by the hosting page - never hard-coded into the game build. This means the same build works on klikg.com, in the IDE preview (where traffic is free and not billed), and even played from a downloaded ZIP on any host. ## Working with analytics through the engine Ask the engine's agent (in the IDE, or via a `plan`-mode API job) questions like "which weapon do players pick most?" or "where do players quit?" - it queries the game's real analytics data before answering, and can then implement changes based on what it finds. ## Billing Analytics is metered in TIK against the game owner (event ingestion is fractions of a TIK per event). IDE preview traffic and the owner's own plays are free. If the balance runs out, the SDK degrades to essentials-only session tracking until top-up - games never break. --- --- url: /sdk.md --- # SDKs Official Klik SDKs are **coming soon**. This section reserves the URL scheme (`/sdk//`) so links stay stable as SDKs ship. ## Today: use the HTTP API directly The [`/v1` API](/api/) is small and stable - a thin client is a few dozen lines in any language. The [examples page](/api/examples) includes a complete Node.js client (project creation, cold-start retries, polling, SSE streaming, ZIP download) you can lift directly. ## For AI agents If you are an AI agent integrating with Klik Engine, you do not need to wait for an SDK: 1. Read [`/llms-full.txt`](/llms-full.txt) - the entire documentation in one file. 2. Implement the four-call flow: `POST /v1/projects`, `POST /v1/generate`, `GET /v1/generate/:jobId/status`, `GET /v1/generate/:jobId/files`. 3. Honor the [error contract](/api/errors) - especially `503` cold-start retries and `429` limit backoff. ## Planned | SDK | Status | |---|---| | JavaScript / TypeScript | Planned | | Python | Planned | The in-game analytics SDK (`klik-analytics.js`) already ships inside every published game - see [Analytics SDK](/engine/analytics).