Skip to content
screenjson

Schema & data

Query ScreenJSON with jq

Useful jq one-liners for extracting counts, cast lists, per-character dialogue, and scene tags from a ScreenJSON document.

Last updated January 2026

Why jq

jq is the reason putting screenplays into JSON stops being abstract and starts being useful. Every question a producer, analyst, or writer has ever asked about a script becomes one pipe away from an answer.

Title, logline, author

jq '.title.en'                        screenplay.json
jq '.logline.en'                      screenplay.json
jq '.authors[] | "\(.given) \(.family)"' screenplay.json

Scene count

jq '.document.scenes | length' screenplay.json

Interior vs. exterior

jq '[.document.scenes[] | select(.heading.context == "INT")] | length' screenplay.json
jq '[.document.scenes[] | select(.heading.context == "EXT")] | length' screenplay.json

Night scenes only

jq '[.document.scenes[] | select(.heading.time == "NIGHT")] | length' screenplay.json

Locations, grouped with scene counts

jq '[.document.scenes[].heading.setting]
      | group_by(.)
      | map({ location: .[0], scenes: length })' screenplay.json

Every character and how many lines they speak

jq '
  [.document.scenes[].body[]
    | select(.type == "dialogue")] as $lines
  | .characters
    | map({
        name: .name,
        lines: ([$lines[] | select(.character == .id)] | length)
      })' screenplay.json

All dialogue for one character

jq --arg id "8d2f-mara" '
  [.document.scenes[].body[]
    | select(.type == "dialogue" and .character == $id)
    | .text.en]' screenplay.json

Every prop across the script

jq '[.document.scenes[].props[]] | unique' screenplay.json

Next