Skip to content
screenjson

Screenplays are data.

ScreenJSON is an open schema and toolchain for treating the screenplay as a first-class, structured document. Convert from Final Draft, Fountain, FadeIn, and PDF. Store it in any NoSQL database, edit whole libraries with teams of AI agents, query it, transform it, render it, ship it to a viewer.

ScreenJSON

ACT I — THE PROBLEM

The screenplay is the last major creative format still locked inside proprietary formats.

A novel is UTF-8. A song is MIDI or stems. A video is MP4 plus sidecar tracks. A screenplay? An .fdx file, a proprietary XML variant, or — more often than anyone wants to admit — a flat PDF that has to be re-parsed every time anything touches it.

That works fine for writing a screenplay. It breaks the moment you want to do anything else: batch-process 5,000 library titles for streaming catalogue search, build an AI tool that understands dialogue per character, version two drafts side by side, or translate a whole film for an international production.

ScreenJSON fixes this by treating the screenplay as what it already is — a structured, hierarchical, typed document — and giving it a proper schema, a proper toolchain, and a proper viewer. Open at the schema layer, licensable at the industrial layer.

INTERCUT

The same scene, two formats.

A single scene from The Heist, on the left as Final Draft's FDX XML, on the right as ScreenJSON. Same information, one of them structured.

Final Draft · FDX XML · proprietary
<Paragraph Type="Scene Heading">
  <Text>INT. VAULT - NIGHT</Text>
</Paragraph>
<Paragraph Type="Action">
  <Text>A single bulb flickers.</Text>
</Paragraph>
<Paragraph Type="Character">
  <Text>MARA</Text>
</Paragraph>
<Paragraph Type="Dialogue">
  <Text>We have ninety seconds.</Text>
</Paragraph>
ScreenJSON JSON · open
{
  "id": "7a1c0b4e-…",
  "heading": {
    "context": "INT.",
    "setting": "VAULT",
    "time":    "NIGHT"
  },
  "body": [
    { "type": "action",
      "text": { "en": "A single bulb flickers." } },
    { "type": "character", "character": "8d2f-mara" },
    { "type": "dialogue",  "character": "8d2f-mara",
      "text": { "en": "We have ninety seconds." } }
  ]
}

Stable UUIDs

Every scene, element, character — addressable forever.

Language maps

Every text field keyed by BCP 47 — en, fr, ja.

Typed elements

Action, cue, dialogue, parenthetical, shot, transition — not layout.

Queryable

jq a catalogue, index it, embed it, retrieve it.

THE SCHEMA

Every part of a screenplay, exactly where you'd expect it.

ScreenJSON models every element a working screenplay actually contains: structured sluglines with context and time-of-day, typed scene bodies with action, dialogue, cues, parentheticals, shots and transitions, a characters index, a revisions log, notes anchored to character ranges, bookmarks, embeddings, passages and summaries for retrieval — and a layout block so renderers can reproduce studio-standard formatting.

Every textual field is keyed by BCP 47 language tag, so localisation is a first-class concern, not an afterthought. Every structural node carries a UUID, so you can point to the exact line of dialogue in an otherwise-identical revision.

{
  "id": "9fea5fc5-f8f9-4c59-85d2-9ec5dcd452c1",
  "version": "1.0.0",
  "title": { "en": "The Heist" },
  "lang": "en",
  "authors": [{ "id": "…", "given": "Jordan", "family": "Lee" }],
  "characters": [
    { "id": "…", "name": "MARA", "traits": ["lead", "thief"] }
  ],
  "document": {
    "cover": { "title": { "en": "The Heist" }, "authors": ["…"] },
    "scenes": [{
      "id": "…",
      "authors": ["…"],
      "heading": { "context": "INT.", "setting": "VAULT", "time": "NIGHT" },
      "body": [
        { "type": "action", "text": { "en": "A single bulb flickers." } },
        { "type": "character", "character": "…" },
        { "type": "dialogue",  "character": "…",
          "text": { "en": "We have ninety seconds." } }
      ]
    }]
  }
}

FADE IN:

Paste a URL. Upload an FDX. See what your screenplay looks like as structured data.

APPENDIX

Start where you are.