Agent Integration Guide

How an LLM agent (Claude Code, Cursor, Codex, or any tool-using model) should use Deckrun.

Deckrun is designed for agents. The API is schema-driven, deterministic, and async-safe. This guide provides the decision logic an agent needs to use Deckrun correctly and reliably.

The agent loop

Discover → Build → Submit → Poll → Deliver

Each stage has a specific API call and a clear exit condition.


1. Discover

Before generating content, fetch the schemas and available resources.

Get the slide format schema (what markdown does Deckrun accept?):

GET /schema?category=slide

Returns the slide format definition including layout directives, surface syntax, notes blocks, timing hints, and supported attributes.

Agents should use this schema to constrain markdown generation and validate output before submission.

List available voices (if narration is needed)

GET /voices

Returns a list of voice resources (see deckrun-voice.json).

List available connectors (where should output be delivered?)

GET /connectors

Returns supported output destination types. Use this to construct a valid output_destination object.


2. Build

Generate markdown that conforms to the slide format schema.

Key conventions

Validate the generated markdown against the schema before submission.


3. Submit

POST /generate
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

{
  "markdown": "...",
  "slide_theme_id": "deckrun-default",
  "output_types": ["pdf", "video", "audio"],
  "voice_id": "<voice_id from GET /voices>",
  "output_destination": {
    "type": "s3",
    "bucket": "my-bucket",
    "prefix": "decks/"
  }
}

Response behavior

For async responses, store the returned job_id and proceed to polling.


4. Poll

GET /jobs/{job_id}
Authorization: Bearer YOUR_API_KEY

Poll until status is terminal:

Status Meaning Action
queued Waiting in queue Wait, retry
processing Rendering in progress Wait, retry
success Complete Retrieve artifacts
failure Error occurred Read error.message, retry or escalate
timeout Time limit exceeded Retry or escalate
cancelled Job cancelled Re-submit if needed

Use queue_position and estimated_wait_seconds to control retry intervals.

Do not poll more frequently than once every 5 seconds.


5. Deliver

On status: "success", the response includes result with URLs for each requested output:

{
  "status": "success",
  "result": {
    "pdf_url": "https://...",
    "video_url": "https://...",
    "audio_url": "https://...",
    "notes_text_url": "https://..."
  }
}

If an output_destination was provided, artifacts are already delivered. URLs remain available for direct access or downstream processing.


Agent-safe conventions


Example: Claude Code integration

import httpx

API_KEY = "..."
BASE = "https://api.agenticdecks.com"

def generate_deck(markdown: str, slide_theme_id: str = "deckrun-default") -> dict:
    resp = httpx.post(
        f"{BASE}/generate",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"markdown": markdown, "slide_theme_id": slide_theme_id, "output_types": ["pdf"]},
    )
    resp.raise_for_status()
    data = resp.json()

    # Synchronous result (PDF-only)
    if data.get("status") == "success":
        return data["result"]

    # Async: poll for completion
    job_id = data["job_id"]
    import time
    while True:
        time.sleep(5)
        r = httpx.get(
            f"{BASE}/jobs/{job_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
        )
        r.raise_for_status()
        job = r.json()
        if job["status"] == "success":
            return job["result"]
        if job["status"] in ("failure", "timeout", "cancelled"):
            raise RuntimeError(f"Job {job_id} failed: {job['error']['message']}")

See also