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.

The agent loop

Discover → Build → Submit → Poll → Deliver

Each stage has a clear 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

This returns the slide format description including layout tags, surface syntax, notes blocks, and supported attributes. Use it to understand what markdown to generate.

List available voices (if narration is needed):

GET /voices

Returns a list of voice resources (deckrun-voice.json). Pick a voice_id with status: "active" and the appropriate tier (system for included, premium for high-fidelity).

List available connectors (where should output go?):

GET /providers

Returns available output connector types. Use to select the right output_destination shape.


2. Build

Generate markdown following the slide format schema. Key conventions:

Validate your markdown against the slide format schema before submitting.


3. Submit

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

{
  "markdown": "...",
  "theme_id": "deckrun-default",
  "outputs": ["pdf", "mp4", "mp3"],
  "voice_id": "deckrun://voices/system-default",
  "output_destination": {
    "type": "s3",
    "bucket": "my-bucket",
    "prefix": "decks/"
  }
}

4. Poll

GET /jobs/{job_id}
Authorization: Bearer YOUR_API_KEY

Poll until status is a terminal value:

Status Meaning Action
queued In queue Wait, retry
processing Generating Wait, retry
success Done Retrieve artifacts
failure Error Read error_message, retry or escalate
timeout Exceeded time limit Retry or escalate
cancelled Cancelled Re-submit if needed

Use queue_position and estimated_wait_seconds to set retry intervals. Do not poll faster than every 5 seconds.


5. Deliver

On status: "success", the response contains artifacts with URLs for each requested output:

{
  "status": "success",
  "artifacts": {
    "pdf": "https://...",
    "mp4": "https://...",
    "mp3": "https://...",
    "notes": "https://..."
  }
}

If you configured an output_destination, artifacts are already delivered there. The URLs are also available for direct download.


Agent-safe conventions


Example: Claude Code integration

import httpx

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

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

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

    # 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["artifacts"]
        if job["status"] in ("failure", "timeout", "cancelled"):
            raise RuntimeError(f"Job {job_id} failed: {job.get('error_message')}")

See also