# AI Tradecraft Serial Studio API

The Serial Studio API manages persistent story worlds and unattended episodic
StoryBook production.

Production base URL:

```text
https://966bpgyzh1.execute-api.us-east-1.amazonaws.com
```

API version: `2026-08-08`

## Authentication

Machine clients send a durable StoryBook API key:

```http
X-API-Key: atc_live_KEY_ID_SECRET
```

Store the key in a server-side secret manager. Never expose it in browser or
mobile application code. Series created with a key belong to that key's Studio
billing account. The key's registered callback URL and webhook secret are
attached to automatically generated episodes.

Examples use:

```bash
export AITRADECRAFT_API_KEY='atc_live_KEY_ID_SECRET'
export AITRADECRAFT_API='https://966bpgyzh1.execute-api.us-east-1.amazonaws.com'
```

All request and response bodies use JSON.

## Series object

```json
{
  "series_id": "ser_50c8e8ec4c1f736e319417bc",
  "status": "draft",
  "title": "Neon Revenant",
  "premise": "A former intelligence courier reads the last eight seconds of violence imprinted on objects while investigating her brother's murder.",
  "genre": "Neo-noir superhero espionage mystery",
  "audience": "Adults 18+",
  "rating": "R",
  "tone": "Colorful, kinetic, intelligent, and emotionally adult.",
  "visual_style": "Cinematic graphic-novel animation with magenta and cyan neon, rain, sharp inked silhouettes, and consistent human faces.",
  "characters": [
    {
      "name": "Mara Vey",
      "description": "29-year-old South Asian woman with a black bob, one silver streak, oxblood jacket, and right-eyebrow scar.",
      "arc": "She fears solving the murder will erase the memories that make her human."
    }
  ],
  "open_threads": ["Who killed Elias Vey?"],
  "movie": {
    "scene_count": 8,
    "voice": "Matthew",
    "include_subtitles": true,
    "include_title": true
  },
  "schedule": {
    "hour": 17,
    "minute": 0,
    "timezone": "America/Los_Angeles"
  },
  "episode_number": 0,
  "recent_episodes": []
}
```

Unknown properties are ignored. Text values are length-limited. A series can
contain 1–12 characters and a movie can contain 3–8 scenes.

## Create a series

`POST /v1/series`

```bash
curl --request POST "$AITRADECRAFT_API/v1/series" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "title": "Neon Revenant",
    "premise": "In Meridian City, Mara Vey investigates her brother’s murder and a conspiracy that manufactures celebrity heroes.",
    "genre": "Neo-noir superhero espionage mystery",
    "audience": "Adults 18+",
    "rating": "R",
    "tone": "Fast, colorful, dangerous, clever, and emotionally adult.",
    "visual_style": "Premium graphic-novel animation, magenta and cyan neon, rain-slick streets, sharp inked silhouettes, consistent adult human faces.",
    "characters": [
      {
        "name": "Mara Vey",
        "description": "29-year-old South Asian woman, angular face, black bob with one silver streak, oxblood jacket, eyebrow scar.",
        "arc": "Must decide whether justice is worth losing her memories."
      },
      {
        "name": "Jonah Vale",
        "description": "34-year-old Black homicide detective, tall and lean, close-cropped hair, midnight-blue suit, gold watch.",
        "arc": "Must choose lawful justice over revenge."
      }
    ],
    "open_threads": [
      "Who killed Elias Vey?",
      "Who manufactures Meridian’s heroes?"
    ],
    "movie": {
      "scene_count": 8,
      "voice": "Matthew",
      "include_subtitles": true,
      "include_title": true
    },
    "schedule": {
      "hour": 17,
      "minute": 0,
      "timezone": "America/Los_Angeles"
    }
  }'
```

Returns `201 Created` with the saved series. New series begin in `draft`.

## List series

`GET /v1/series`

```bash
curl "$AITRADECRAFT_API/v1/series" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY"
```

```json
{"items": [{"series_id": "ser_50c8e8ec4c1f736e319417bc", "status": "active", "title": "Neon Revenant"}]}
```

## Retrieve a series

`GET /v1/series/{series_id}`

```bash
curl "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY"
```

## Update a series

`PATCH /v1/series/{series_id}`

Only supplied properties change. If an active series's schedule changes, its
EventBridge schedule is updated immediately.

```bash
curl --request PATCH \
  "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "schedule": {"hour": 18, "minute": 30, "timezone": "America/New_York"},
    "tone": "Faster action with dry humor and morally difficult choices."
  }'
```

## Preview the next episode

`POST /v1/series/{series_id}/preview`

Preview writes the prospective narration but does not create a movie, reserve
credits, publish, or advance continuity.

```bash
curl --request POST \
  "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc/preview" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

```json
{
  "status": "dry-run",
  "series_id": "ser_50c8e8ec4c1f736e319417bc",
  "episode": 1,
  "title": "Eight Seconds Missing",
  "narration": "Rain fractured the city’s neon...",
  "summary": "Mara recovers evidence from an ambush.",
  "cliffhanger": "The photograph bears tomorrow’s timestamp.",
  "audience_question": "Who can create evidence before the crime occurs?"
}
```

## Generate an episode now

`POST /v1/series/{series_id}/episodes`

```bash
curl --request POST \
  "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc/episodes" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY" \
  --header 'Idempotency-Key: neon-revenant-2026-08-08' \
  --header 'Content-Type: application/json' \
  --data '{}'
```

```json
{
  "status": "submitted",
  "series_id": "ser_50c8e8ec4c1f736e319417bc",
  "episode": 1,
  "job_id": "0b80ea54-3cf8-46ea-b6c1-c46da1d57d40",
  "title": "Eight Seconds Missing"
}
```

One normal episode is allowed per series per local calendar day. Repeated calls
return the original run record. The public API does not accept a force override.

Rendering remains asynchronous. Use the existing endpoint to poll the returned
job:

```bash
curl "$AITRADECRAFT_API/v1/storybooks/JOB_ID" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY"
```

When rendering finishes, the registered callback receives the existing
`storybook.completed` or `storybook.failed` signed webhook.

## List recent episodes

`GET /v1/series/{series_id}/episodes`

Returns the twenty most recent continuity records:

```bash
curl "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc/episodes" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY"
```

## Activate daily production

`POST /v1/series/{series_id}/activate`

```bash
curl --request POST \
  "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc/activate" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY" \
  --header 'Content-Type: application/json' --data '{}'
```

The schedule uses the series timezone and follows daylight-saving changes.
Failures retry twice within one hour.

## Pause daily production

`POST /v1/series/{series_id}/pause`

Pausing disables future scheduled invocations without deleting continuity.

```bash
curl --request POST \
  "$AITRADECRAFT_API/v1/series/ser_50c8e8ec4c1f736e319417bc/pause" \
  --header "X-API-Key: $AITRADECRAFT_API_KEY" \
  --header 'Content-Type: application/json' --data '{}'
```

## Archive a series

`DELETE /v1/series/{series_id}`

Archiving disables scheduling and hides the series. It does not erase rendered
movies or billing records.

## Webhooks

Serial episodes use the StoryBook webhook format documented in
`STORYBOOK_AUTOMATION_USER_MANUAL.md`. Verify `X-AITradecraft-Signature` as
HMAC-SHA256 over:

```text
X-AITradecraft-Timestamp + "." + exact_raw_request_body
```

The `external_id` for a serial episode is `series_id:episode_number`.

## Errors

| HTTP | Meaning |
|---:|---|
| `400` | Invalid series field, schedule, character, or movie setting. |
| `401` | Missing or invalid API key. |
| `404` | Series does not exist for this billing account. |
| `422` | Episode exceeds the API key spending ceiling. |
| `500` | Temporary generation, billing, scheduling, or rendering failure. |

Retry server errors with exponential backoff. Normal episode creation is
calendar-day idempotent, so a retry does not intentionally create a duplicate.
