null in a Simkl response is never noise — it’s one of five specific signals. This page is the master reference; schema descriptions link back here by type.
Type 1
Never happened yet — event hasn’t fired
Type 2
Doesn’t apply — key omitted entirely
Type 3
Empty result — whole response null
Type 4
Unknown — data not on file
Type 5
End state — journey complete
Type 1 — Never happened yet
Where you’ll see it
Handling
Type 2 — Doesn’t apply to this type
Where you’ll see it
See Watchlist statuses for the full per-type matrix.
/sync/all-items/anime entries wrap in show:, by design. Each
item in the anime array nests its media object under a key called
show:, not anime:. This is intentional cross-catalog compatibility:
apps that source their data from TMDB or TVDB treat anime as shows
(those catalogs have no separate “anime” concept), so the show:
wrapper keeps Simkl’s sync responses drop-in compatible with code
written against TMDB/TVDB-shaped data. Anime-only fields (anime_type,
mal/anidb/anilist/kitsu IDs) sit alongside on the outer item and on
show.ids respectively.Type 3 — Empty result set
The whole response is
null or an empty array — the endpoint accepted the request but there are no items to return. The URL is valid; the call returns 200; the body is just empty.
Handling
Type 4 — Unknown / data not on file
Field present, value
null — the data point is supposed to have a value but Simkl genuinely doesn’t have it yet. Render a placeholder; don’t display the literal null.network reflects the upstream catalog (TVDB). The value is what
TVDB classifies the record under — for streaming-only shows TVDB lists
the platform as the “network” ("Prime Video", "Netflix", "Apple TV+"),
for traditional broadcast it’s the broadcaster ("HBO", "AMC", "CBS").
Don’t infer distribution model from this field; treat it as an opaque
display string from the source catalog.memo: {} is a Type 4 variant. On
GET /sync/all-items?memos=yes,
items the user has set a memo on return:null, NOT missing — {}. The empty-object marker keeps the key
shape consistent (client code can always do item.memo.text || ''
without an existence check or a null-coalesce). When ?memos=yes is
NOT set, the memo key is omitted entirely (Type 2).Type 5 — End state reached
Field present, value
null — the value used to be meaningful but the workflow has ended; the field is intentionally cleared. Render the “complete” state in your UI.
Handling
Empty / Missing response shape — by endpoint
The API uses five different shapes for “this request was valid but there’s no data”. The table below tells you what to expect at each endpoint so a single parsing path can handle them all.The five shapes you’ll meet
200 [ ]
Empty array. Safe to iterate.
200 null
Top-level
null. r.json() returns None.200 { }
Empty object.
len() is 0.301 redirect
Answer in
Location: header. No body.200 fallthrough
Server returned unrelated discover data instead of an error.
Per-endpoint shape matrix
Defensive parser pattern
If you’re writing a generic Simkl client wrapper, this defensive pattern handles every shape above:Pinning a shape in your code
If your integration depends on a specific row of this table, pin it as a comment in your code. When the table changes on a future doc release, your in-code reference makes the diff easier to spot during a routine dependency-update review.Quick decision table
Related
Watchlist statuses
Which statuses are valid per type. The reason
watching and hold are omitted from movie blocks (Type 2).Standard media objects
Field-by-field shape of Movie / Show / Anime / Episode — which fields can be null, which are always present.
Dates and timezones
ISO-8601, the
Z suffix, and the 1970-01-01T00:00:01Z “very long time ago” placeholder.Errors
How error envelopes differ from null responses, and when you’ll see each.