Skip to main content
This page is the complete reference for the listener GraphQL schema. For setup, authentication, and the in-browser playground, start with GraphQL. All operations are scoped to one station by the URL: /api/v1/stations/{stationSlug}/graphql, with GET or POST. Every query needs a Bearer credential with listener:read. All data is published-only, matching the HTTP API.

Conventions

  • ! means non-null. A field without ! can be null; a required nullable field is still always present in the response when you select it.
  • IDs are strings. Content, broadcast, program, and presenter IDs are UUIDs; the station id is a station identifier and is separate from the slug. Pagination cursors are opaque strings, even where the type is ID.
  • Timestamps such as startsAt and observedAt are ISO 8601 strings in UTC. Dates such as fromDate are local YYYY-MM-DD strings; interpret them in the station’s timezone.
  • Selection is required. GraphQL returns only the fields you list. There is no *; ask for each field you need.
  • contractVersion is exposed on Station, PublishedRecord, Schedule, Programs, CurrentBroadcast, NowPlaying, and TrackHistory. Check that it equals 1 in your client. ContentSchema, ContentCollection, Weather, Traffic, and RevisionPreview do not expose it in GraphQL.
  • Aliases let you call one field twice with different arguments in a single request.

Queries

station

The station entry document. profile holds the public station details once the station has saved them. resources lists the REST paths for each resource, and a null entry means that resource is disabled or not entitled. Check resources.<name> before querying a resource that can be disabled. resources.realtime tells a client where to follow the station’s public realtime feed. REST equivalent: GET /api/v1/stations/{stationSlug}.

schemas

Returns the published content type definitions, or one type when type is set. Use them to interpret the values of a record. Passing version without type returns VALIDATION_ERROR. REST equivalent: GET …/schemas.

content

Returns published records of one type, newest first by default. nextCursor is null on the last page. A cursor only works with the same sort and direction that produced it; otherwise the call returns VALIDATION_ERROR. Returns NOT_FOUND when station.resources.content is null. Filtering on a field that is not a delivery field of the type, or is not a text or choice field, returns VALIDATION_ERROR. An unknown type returns an empty page, or NOT_FOUND when you pass a filter. REST equivalent: GET …/content?type=<key>, with the same sort, direction, and filter parameters.

contentRecord

One published record by UUID. Returns NOT_FOUND when the record is unpublished, belongs to another station, or the content resource is disabled. A non-UUID id returns VALIDATION_ERROR. REST equivalent: GET …/content/{id}.

contentBySlug

The published record a slug names. A slug the record used before also resolves, and returns the record as it is now. Compare values.slug with the slug you requested, and redirect to the current URL when they differ. Returns NOT_FOUND when no published record of that type has used the slug, or the content resource is disabled. REST equivalent: GET …/content/{type}/by-slug/{slug}.

schedule

Broadcasts in the window, up to 31 inclusive days and 1000 broadcasts. truncated is true when more broadcasts exist than were returned; narrow the window and request again. REST equivalent: GET …/schedule.

programs

Same window arguments as schedule. Returns the programs in the window with their presenters and regular slots, and echoes fromDate and throughDate. REST equivalent: GET …/programs.

currentBroadcast

The live or current-window broadcast. broadcast is null when nothing is on air. asOf is the instant the answer was computed. REST equivalent: GET …/broadcast/current.

nowPlaying

The latest reported track from external automation. track is null with freshness.status "empty" when nothing was reported. elapsedSeconds and endsAt are computed per request and are null when the duration is unknown or the track is not playing. REST equivalent: GET …/now-playing.

trackHistory

Reported track observations for tracks that were playing, newest first, with cursor pagination. Duplicate titles at different times are separate entries. REST equivalent: GET …/track-history.

weather

Normalized weather for the station’s coverage areas. Returns null when weather redistribution is not enabled for the station; there is no error in that case. See Weather JSON for the shape of snapshots. REST equivalent: GET …/weather.

traffic

Normalized traffic for the station’s watched roads. Returns null when traffic redistribution is not enabled. See Traffic JSON for the shape of snapshot. REST equivalent: GET …/traffic.

Mutations

previewEditorial

Renders a specific revision of a record for a headless site’s preview mode. Send it with POST and both headers:
input.stationId must match the station in the URL, otherwise the call returns NOT_FOUND. A missing X-Preview-Grant returns UNAUTHENTICATED. Call it from your server so the grant and token stay out of the browser. REST equivalent: POST /api/v1/preview/editorial.

Object types

Station

StationProfile

Each nullable field is null when the station has not filled it in.

StationAddress

StationResources

Each field except realtime is a path (or path prefix) for the matching REST resource. A null value means the resource is disabled, unpublished, or not entitled.

StationRealtime

The station’s public realtime feed. Connect to url without a credential. Pass the whole object to the SDK’s subscribePublicFeed, or let client.subscribe read it for you. See Public realtime feed and the TypeScript SDK.

StationDelivery

ContentSchema

ContentCollection

PublishedRecord

PublishedRelated

PublicMedia

url is the original file. Use variants for list pages and srcset, and width and height to reserve the aspect ratio.

PublicMediaVariants

Each field is a URL, or null when the rendition does not exist, for example for audio.

Schedule

Broadcast

BroadcastProgram

ProgramSummary

ProgramSlot

A regular slot, such as “Saturday 10:00 for 120 minutes, every week”.

BroadcastPresenter

Programs

CurrentBroadcast

NowPlaying

PlaybackTrack and HistoryEntry

HistoryEntry has the same fields as PlaybackTrack plus an id.

PlaybackFreshness

TrackHistory

Weather

Traffic

RevisionPreview

Enums

ContentSort

SortDirection

ContentFilterOp

Input types

ContentFilter

The REST equivalents are field:value, field.contains:value, and field.anyOf:a,b.

PreviewInput

JSON scalar shapes

Fields typed JSON return arbitrary JSON, so you cannot select sub-fields. Parse them in your client. All units match Field types and empty states.

Schema field JSON

ContentSchema.fields is an array of field definitions:
kind is one of text, rich_text, number, boolean, datetime, choices, media, content, or group. See Field types and empty states for rendering guidance.

Weather JSON

Weather.snapshots is an array. Each element has this shape:
The values above are illustrative. conditionCode is one of Clear, MostlyClear, PartlyCloudy, Cloudy, Fog, Drizzle, FreezingDrizzle, Rain, HeavyRain, FreezingRain, Snow, HeavySnow, Flurries, Showers, SnowShowers, Thunderstorm, or SevereThunderstorm.

Traffic JSON

Traffic.snapshot has this shape:
The values above are illustrative. An empty incidents array with freshness.status of fresh means no incidents on the watched roads.

Errors

A failed operation returns HTTP status from the most severe error code, plus a standard GraphQL errors array. Branch on errors[i].extensions.code. A switched-off module shows up as a null resource and NOT_FOUND in GraphQL, not as the REST code MODULE_DISABLED. Errors raised by GraphQL itself, such as an unknown field or a missing required variable, have no extensions.code. Fix the query rather than retrying. When a query asks for several fields and one fails, the response can carry both data and errors. Check errors before trusting data. Requests that fail before the query runs, such as an invalid token or an unknown station, return the REST error body { "error": { "code", "message", "requestId" } }. Every response includes an x-request-id header you can quote to support.

More examples

Several resources in one request

Aliases and fragments

Content types and their fields

Request one type, or a historical version of it:

Programs in a window

Weather and traffic

Both fields are null when the station has no entitlement, so handle that before reading the JSON.

Follow pagination

Stop when nextCursor is null. Do not reuse a cursor across content types.

Simple read with GET

Pass variables and extensions as JSON-encoded strings, and operationName as plain text. GET runs queries only.

Full schema

This is the schema definition language (SDL) for the listener API.