> ## Documentation Index
> Fetch the complete documentation index at: https://api.simkl.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Find items by external ID

> > ## ⚠️ Prefer [`GET /redirect`](/api-reference/redirect) + a cached detail endpoint over `/search/id` for almost every external-ID lookup
>
> The recommended two-step flow is materially cheaper, faster, and edge-cached:
>
> **Step 1 — Resolve the external ID to a Simkl ID.** Call [`GET /redirect?to=simkl&<external_id>=…`](/api-reference/simkl/redirect) and **read** (don't follow) the `Location` header. Parse the Simkl ID out of the URL path. No JSON body to download, no JSON to parse — just HTTP headers.
>
> **Step 2 — Fetch the full record from the cached detail endpoint.** Use the parsed Simkl ID with the matching:
> - Movies → [`GET /movies/{simkl_id}`](/api-reference/simkl/get-movie)
> - TV shows → [`GET /tv/{simkl_id}`](/api-reference/simkl/get-tv-show)
> - Anime → [`GET /anime/{simkl_id}`](/api-reference/simkl/get-anime)
> - Episode lists → [`GET /tv/episodes/{simkl_id}`](/api-reference/simkl/get-tv-episodes) or [`GET /anime/episodes/{simkl_id}`](/api-reference/simkl/get-anime-episodes)
>
> These detail endpoints are **Cloudflare-cached by Simkl ID** with **automatic server-side cache invalidation** on metadata updates. Popular titles come straight from the edge cache and cost almost nothing.
>
> **Why this beats `/search/id`:**
> - `/redirect` returns just HTTP headers (no JSON body). `/search/id` returns JSON every call.
> - The detail endpoints are Cloudflare-cached. `/search/id` is a search query that hits origin every time.
> - Two requests both cheap > one request that always hits origin.
> - Concurrent / parallel lookups against the cached detail endpoints are explicitly allowed (see [Rate limits → Parallel requests](/resources/rate-limits#parallel-requests--when-allowed)). `/search/id` should be called sequentially.
>
> **When `/search/id` is still the right call** (rare):
> - You need the [legacy response shape](#response) for a code path you can't change.
> - You need a type-agnostic lookup that returns the `type` field upfront without parsing the `Location` URL.

---

Look up Simkl records by any external ID — IMDB, TMDB, TVDB, MAL, AniDB, AniList, Kitsu, anisearch, anime-planet, livechart, letterboxd, Netflix, Trakt slug. Pass the ID as a query parameter (e.g. `?imdb=tt4574334`).

#### Response shape (per item)

```json
{
  "type": "anime",
  "title": "Attack on Titan",
  "poster": "39/396870bc78f2ba7e",
  "year": 2013,
  "status": "ended",
  "total_episodes": 75,
  "anime_type": "tv",
  "ids": {
    "simkl": 39687,
    "slug": "attack-on-titan"
  },
  "mal": {
    "id": 16498,
    "type": "tv"
  }
}
```

`status` is one of `released`, `upcoming`, `ended`, `aired`, `tba`. `total_episodes` is omitted for movies.

<Card title="Redirect & deep-linking — recommended alternative" icon="bolt" href="/api-reference/redirect" horizontal>
 Full walkthrough of the two-step `/redirect` → cached detail endpoint flow, with the stop-at-301 reference table for popular HTTP clients and worked recipes in bash, JavaScript, and Python.
</Card>

<Tip>
**Which IDs can I send/expect?** All accepted input identifiers and the keys you'll see echoed back in responses are listed at [**Standard media objects → Supported ID keys**](/conventions/standard-media-objects#supported-id-keys). Send every ID you have on writes — Simkl picks the first that resolves and ignores the rest. Reminder: `slug` is **response-only** (never send it on a request).
</Tip>



## OpenAPI

````yaml /openapi.json get /search/id
openapi: 3.1.0
info:
  title: Simkl API
  version: 1.0.0
  description: >-
    The **Simkl API** lets you build apps that track Movies, TV Shows, and Anime
    — scrobble playback, sync watch history, and pull rich metadata.


    All requests use HTTPS and return JSON. The base URL is
    `https://api.simkl.com`.


    **Every request needs three URL parameters and a `User-Agent` header:**


    ```

    /endpoint?client_id=YOUR_CLIENT_ID&app-name=my-app&app-version=1.0

    ```


    See [Headers and required parameters](/conventions/headers) for the full
    reference. Endpoints that read or modify a user's data also need an
    `Authorization: Bearer <token>` header — see [OAuth
    2.0](/api-reference/oauth) or the [PIN flow](/api-reference/pin).


    > ⚠️ **About the auto-rendered cURL examples on each endpoint page:** they
    omit `?client_id=…&app-name=…&app-version=…` from the URL for brevity. **You
    must add them yourself when copy-pasting**, or use the interactive **"Try
    it"** playground (it fills them in for you). This is a Mintlify rendering
    convention — every Mintlify-built API doc behaves the same way.


    **Get started**


    - [Quickstart](/quickstart) — first request in 60 seconds

    - [API rules](/api-rules) — what's allowed, what isn't

    - [Standard media objects](/conventions/standard-media-objects) — the shapes
    every endpoint speaks

    - [Errors](/conventions/errors) — every status code Simkl returns
  contact:
    name: Simkl Developer Support
    url: https://support.simkl.com
  termsOfService: https://simkl.com/about/policies/terms/
  license:
    name: Simkl API Terms of Use
    url: https://simkl.com/about/policies/terms/
  x-logo:
    url: https://i.simkl.com/img_tv/apiary_logo_api.png
    backgroundColor: '#0E5DAB'
    altText: Simkl
servers:
  - url: https://api.simkl.com
    description: Production API
  - url: https://data.simkl.in
    description: CDN for static, public data files (Calendar + Trending). No auth required.
security:
  - clientId: []
  - simklApiKey: []
tags:
  - name: OAuth 2.0
    description: >-
      OAuth 2.0 authorization-code flow for web and mobile apps. The user is
      redirected to Simkl, signs in, approves your app, and is redirected back
      with a `code` you exchange for an `access_token`. Long-lived tokens — no
      refresh-token flow needed.
    externalDocs:
      description: OAuth 2.0 walkthrough
      url: https://api.simkl.org/api-reference/oauth
  - name: PIN
    description: >-
      Device flow for TVs, consoles, smart watches, CLI tools — anywhere typing
      a URL is hard. Show a 5-character code; user enters it on simkl.com/pin;
      you poll for the access token. **No `client_secret` required.**
    externalDocs:
      description: PIN flow walkthrough
      url: https://api.simkl.org/api-reference/pin
  - name: Redirect
    description: >-
      Helper redirects for one-click "mark as watched", trailers, sharing, and
      more.
  - name: Search
    description: Find shows, movies, and anime by ID, text query, file name, or randomly.
    externalDocs:
      description: Search guide
      url: https://api.simkl.org/guides/search
  - name: Movies
    description: >-
      Browse the Simkl movies catalog: details, premieres, top-of-best, and
      genre filters.
  - name: TV
    description: >-
      Browse the Simkl TV catalog: details, episodes, what's airing, premieres,
      top-of-best, and genre filters.
  - name: Anime
    description: >-
      Browse the Simkl anime catalog: details, episodes, what's airing,
      premieres, top-of-best, and genre filters.
  - name: Ratings
    description: >-
      Read Simkl's average community rating, rank, drop rate, and external
      ratings (IMDB, MAL) for any item, or for every item in a user's lists.
  - name: Scrobble
    description: >-
      Report real-time playback to Simkl with `start`, `pause`, and `stop`. At ≥
      80 % progress Simkl marks the item as watched automatically; below 80 %
      the session is saved as a paused playback the user can resume from any
      device.


      See [Standard media objects](/conventions/standard-media-objects) for the
      supported ID keys.


      <!-- IDS_TABLE_START -->


      ### Supported ID keys


      Inside any `ids` object, pass as many of these as you have. Simkl resolves
      to the canonical record.


      | ID key | Type | Example |

      |---|---|---|

      | `simkl` | integer | `49108`. Simkl's canonical ID. Most reliable. |

      | `imdb` | string | `tt1520211` |

      | `tmdb` | integer | `76757` (for TV, specify `type`) |

      | `tvdb` | int / string | `153021` or `the-walking-dead` |

      | `mal` | integer | `4246` (MyAnimeList) |

      | `anidb` | integer | `10846`. Specifying just this is enough for anime
      lookups. |

      | `anilist` | integer | `21` |

      | `kitsu` | integer | `12` |

      | `anisearch` | integer | `2227` |

      | `animeplanet` | string | `one-piece` |

      | `livechart` | integer | `321` |

      | `letterboxd` | string | `the-truman-show` |

      | `netflix` | integer | `70210890` (movie ID) |

      | `traktslug` | string | `john-wick-chapter-4-2023` |


      > 📖 Full reference: [Standard media
      objects](/conventions/standard-media-objects)


      <!-- IDS_TABLE_END -->
    externalDocs:
      description: Scrobble guide
      url: https://api.simkl.org/guides/scrobble
  - name: Sync
    description: >-
      Use Simkl as a cloud backup for the user's watch history and lists
      (Watching, Plan to Watch, On Hold, Dropped, Completed). **Always check
      [`/sync/activities`](/api-reference/simkl/get-activities) first** and sync
      only the lists that have moved.


      All write endpoints accept arrays — batch aggressively. See [Standard
      media objects](/conventions/standard-media-objects) for the supported ID
      keys.


      <!-- IDS_TABLE_START -->


      ### Supported ID keys


      Inside any `ids` object, pass as many of these as you have. Simkl resolves
      to the canonical record.


      | ID key | Type | Example |

      |---|---|---|

      | `simkl` | integer | `49108`. Simkl's canonical ID. Most reliable. |

      | `imdb` | string | `tt1520211` |

      | `tmdb` | integer | `76757` (for TV, specify `type`) |

      | `tvdb` | int / string | `153021` or `the-walking-dead` |

      | `mal` | integer | `4246` (MyAnimeList) |

      | `anidb` | integer | `10846`. Specifying just this is enough for anime
      lookups. |

      | `anilist` | integer | `21` |

      | `kitsu` | integer | `12` |

      | `anisearch` | integer | `2227` |

      | `animeplanet` | string | `one-piece` |

      | `livechart` | integer | `321` |

      | `letterboxd` | string | `the-truman-show` |

      | `netflix` | integer | `70210890` (movie ID) |

      | `traktslug` | string | `john-wick-chapter-4-2023` |


      > 📖 Full reference: [Standard media
      objects](/conventions/standard-media-objects)


      <!-- IDS_TABLE_END -->
    externalDocs:
      description: Sync guide
      url: https://api.simkl.org/guides/sync
  - name: Users
    description: User profile, settings, and watch statistics.
externalDocs:
  description: Simkl API documentation
  url: https://api.simkl.org
paths:
  /search/id:
    get:
      tags:
        - Search
      summary: Find items by external ID
      description: >-
        > ## ⚠️ Prefer [`GET /redirect`](/api-reference/redirect) + a cached
        detail endpoint over `/search/id` for almost every external-ID lookup

        >

        > The recommended two-step flow is materially cheaper, faster, and
        edge-cached:

        >

        > **Step 1 — Resolve the external ID to a Simkl ID.** Call [`GET
        /redirect?to=simkl&<external_id>=…`](/api-reference/simkl/redirect) and
        **read** (don't follow) the `Location` header. Parse the Simkl ID out of
        the URL path. No JSON body to download, no JSON to parse — just HTTP
        headers.

        >

        > **Step 2 — Fetch the full record from the cached detail endpoint.**
        Use the parsed Simkl ID with the matching:

        > - Movies → [`GET /movies/{simkl_id}`](/api-reference/simkl/get-movie)

        > - TV shows → [`GET /tv/{simkl_id}`](/api-reference/simkl/get-tv-show)

        > - Anime → [`GET /anime/{simkl_id}`](/api-reference/simkl/get-anime)

        > - Episode lists → [`GET
        /tv/episodes/{simkl_id}`](/api-reference/simkl/get-tv-episodes) or [`GET
        /anime/episodes/{simkl_id}`](/api-reference/simkl/get-anime-episodes)

        >

        > These detail endpoints are **Cloudflare-cached by Simkl ID** with
        **automatic server-side cache invalidation** on metadata updates.
        Popular titles come straight from the edge cache and cost almost
        nothing.

        >

        > **Why this beats `/search/id`:**

        > - `/redirect` returns just HTTP headers (no JSON body). `/search/id`
        returns JSON every call.

        > - The detail endpoints are Cloudflare-cached. `/search/id` is a search
        query that hits origin every time.

        > - Two requests both cheap > one request that always hits origin.

        > - Concurrent / parallel lookups against the cached detail endpoints
        are explicitly allowed (see [Rate limits → Parallel
        requests](/resources/rate-limits#parallel-requests--when-allowed)).
        `/search/id` should be called sequentially.

        >

        > **When `/search/id` is still the right call** (rare):

        > - You need the [legacy response shape](#response) for a code path you
        can't change.

        > - You need a type-agnostic lookup that returns the `type` field
        upfront without parsing the `Location` URL.


        ---


        Look up Simkl records by any external ID — IMDB, TMDB, TVDB, MAL, AniDB,
        AniList, Kitsu, anisearch, anime-planet, livechart, letterboxd, Netflix,
        Trakt slug. Pass the ID as a query parameter (e.g. `?imdb=tt4574334`).


        #### Response shape (per item)


        ```json

        {
          "type": "anime",
          "title": "Attack on Titan",
          "poster": "39/396870bc78f2ba7e",
          "year": 2013,
          "status": "ended",
          "total_episodes": 75,
          "anime_type": "tv",
          "ids": {
            "simkl": 39687,
            "slug": "attack-on-titan"
          },
          "mal": {
            "id": 16498,
            "type": "tv"
          }
        }

        ```


        `status` is one of `released`, `upcoming`, `ended`, `aired`, `tba`.
        `total_episodes` is omitted for movies.


        <Card title="Redirect & deep-linking — recommended alternative"
        icon="bolt" href="/api-reference/redirect" horizontal>
         Full walkthrough of the two-step `/redirect` → cached detail endpoint flow, with the stop-at-301 reference table for popular HTTP clients and worked recipes in bash, JavaScript, and Python.
        </Card>


        <Tip>

        **Which IDs can I send/expect?** All accepted input identifiers and the
        keys you'll see echoed back in responses are listed at [**Standard media
        objects → Supported ID
        keys**](/conventions/standard-media-objects#supported-id-keys). Send
        every ID you have on writes — Simkl picks the first that resolves and
        ignores the rest. Reminder: `slug` is **response-only** (never send it
        on a request).

        </Tip>
      operationId: get-search-id
      parameters:
        - name: simkl
          in: query
          description: Simkl `id`.
          schema:
            type: integer
          example: '2090'
        - name: hulu
          in: query
          description: hulu_id. All other parameters can be empty if this one specified.
          schema:
            type: integer
          example: '752375'
        - name: netflix
          in: query
          description: Netflix `movieid`, this parameter is in beta and may not work.
          schema:
            type: integer
          example: '70210890'
        - name: mal
          in: query
          description: MyAnimeList `id`.
          schema:
            type: integer
          example: '4246'
        - name: tvdb
          in: query
          description: TVDB ID. All other parameters can be empty if this one specified.
          schema:
            type: string
          example: 153021, the-walking-dead
        - name: tmdb
          in: query
          description: >-
            The Movie Database (TMDb) ID. All other parameters can be empty if
            this one specified. `type` parameter is required if you want to
            search for TV Shows
          schema:
            type: integer
          example: '76757'
        - name: imdb
          in: query
          description: >-
            can be IMDB ID or full IMDB URL. All other parameters can be empty
            if this one specified.
          schema:
            type: string
            pattern: ^tt\d+$
          example: tt1972591
        - name: anidb
          in: query
          description: AniDB ID. All other parameters can be empty if this one specified.
          schema:
            type: integer
          example: '10846'
        - name: crunchyroll
          in: query
          description: Crunchyroll ID. You can pass episode ID or url ID(sword-art-online)
          schema:
            type: string
          example: '656641'
        - name: anilist
          in: query
          description: AniList ID
          schema:
            type: integer
          example: '21'
        - name: kitsu
          in: query
          description: Kitsu ID
          schema:
            type: integer
          example: '12'
        - name: livechart
          in: query
          description: LiveChart ID
          schema:
            type: integer
          example: '321'
        - name: anisearch
          in: query
          description: aniSearch ID
          schema:
            type: integer
          example: '2227'
        - name: animeplanet
          in: query
          description: Anime-Planet ID
          schema:
            type: string
          example: one-piece
        - name: type
          in: query
          description: Only used when sending tmdb.
          schema:
            type: string
            enum:
              - show
              - movie
        - name: title
          in: query
          description: >-
            TV show, anime, or movie title. If this title has more then 1 item
            then null will be returned, add more fields to narrow down the
            search to 1 item(such as type,year etc.)
          schema:
            type: string
          example: The Walking Dead
        - name: year
          in: query
          description: release year.
          schema:
            type: integer
          example: '2010'
        - $ref: '#/components/parameters/ClientIdQuery'
        - $ref: '#/components/parameters/AppNameQuery'
        - $ref: '#/components/parameters/AppVersionQuery'
        - $ref: '#/components/parameters/UserAgentHeader'
        - name: anfo
          in: query
          required: false
          schema:
            type: string
          example: '12345'
          description: >-
            AniFox / anfo.org ID. Returns the matching Simkl title(s). See
            [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: ann
          in: query
          required: false
          schema:
            type: integer
          example: 4658
          description: >-
            Anime News Network (ANN) ID. Returns the matching Simkl title(s).
            See [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: tvcom
          in: query
          required: false
          schema:
            type: string
          example: '12345'
          description: >-
            TV.com ID (legacy). Returns the matching Simkl title(s). See
            [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: zap2it
          in: query
          required: false
          schema:
            type: string
          example: SH00726133
          description: >-
            Zap2it (TVScheduleDirect) ID. Returns the matching Simkl title(s).
            See [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: traktslug
          in: query
          required: false
          schema:
            type: string
          example: stranger-things
          description: >-
            Trakt URL slug. Returns the matching Simkl title(s). See [Standard
            media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: letterboxd
          in: query
          required: false
          schema:
            type: string
          example: parasite-2019
          description: >-
            Letterboxd film slug (movies). Returns the matching Simkl title(s).
            See [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: boxd
          in: query
          required: false
          schema:
            type: string
          example: parasite-2019
          description: >-
            Letterboxd alias — same as `letterboxd`. Returns the matching Simkl
            title(s). See [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
        - name: mdl
          in: query
          required: false
          schema:
            type: string
          example: crash-landing-on-you
          description: >-
            MyDramaList slug or ID (Korean / Asian dramas). Returns the matching
            Simkl title(s). See [Standard media objects → Supported ID
            keys](/conventions/standard-media-objects#supported-id-keys).
      responses:
        '200':
          description: >-
            Array of matching catalog records — `[]` when no record matches the
            supplied IDs. There is no `404` for unknown IDs; an empty array is
            the not-found shape (Type 3 null — see [Null and missing
            values](/conventions/null-values)).
          headers: {}
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SearchByIdResultItem'
              examples:
                imdb_movie:
                  summary: IMDB ID → movie (Inception)
                  description: >-
                    The most common use case: a tracker app has an IMDB id from
                    its local catalog and wants the Simkl id to deep-link or
                    sync against. Pass `?imdb=tt…` — Simkl returns the canonical
                    movie record.
                  value:
                    - type: movie
                      title: Inception
                      poster: 14/14017865947c9d3d0d
                      year: 2010
                      status: released
                      ids:
                        simkl: 472214
                        slug: inception
                tmdb_movie:
                  summary: TMDB ID + `?type=movie` → movie (Inception)
                  description: >-
                    TMDB indexes movies and TV in separate id sequences, so the
                    same numeric id can refer to either. Always pair `?tmdb=…`
                    with `?type=movie` or `?type=tv` to disambiguate. This
                    example resolves Inception's TMDB id 27205 as a movie.
                  value:
                    - type: movie
                      title: Inception
                      poster: 14/14017865947c9d3d0d
                      year: 2010
                      status: released
                      ids:
                        simkl: 472214
                        slug: inception
                tmdb_tv:
                  summary: TMDB ID + `?type=tv` → TV show (Game of Thrones)
                  description: >-
                    Same TMDB disambiguation pattern as `tmdb_movie` above, but
                    for a TV show. TV results additionally carry
                    `total_episodes`.
                  value:
                    - type: tv
                      title: Game of Thrones
                      poster: 57/5742576cd8f59fcb0
                      year: 2011
                      status: ended
                      ids:
                        simkl: 17465
                        slug: game-of-thrones
                      total_episodes: 73
                tvdb_tv:
                  summary: TVDB ID → TV show (The Walking Dead)
                  description: >-
                    TVDB has no movie type, so the response always shapes as
                    `type: tv` (or `type: anime` for anime catalogued at TVDB).
                  value:
                    - type: tv
                      title: The Walking Dead
                      poster: 16/16913426086fc13
                      year: 2010
                      status: ended
                      ids:
                        simkl: 2090
                        slug: the-walking-dead
                      total_episodes: 177
                mal_anime:
                  summary: >-
                    MAL ID → anime (Demon Slayer; carries `anime_type` + `mal`
                    blocks)
                  description: >-
                    Anime results carry two extra fields the other types don't:
                    `anime_type` (catalog format — `tv`, `movie`, `ova`, `ona`,
                    `special`, `music video`) and `mal` (the MyAnimeList id +
                    MAL's own type taxonomy).
                  value:
                    - type: anime
                      title: Kimetsu no Yaiba
                      poster: 85/85964029165a0e752
                      year: 2019
                      status: ended
                      ids:
                        simkl: 831411
                        slug: kimetsu-no-yaiba
                      total_episodes: 26
                      anime_type: tv
                      mal:
                        id: 38000
                        type: tv
                simkl_id_roundtrip:
                  summary: Simkl ID → same record (round-trip)
                  description: >-
                    Useful for validating that a Simkl id you cached is still
                    resolvable. Same shape as the IMDB-lookup case.
                  value:
                    - type: movie
                      title: Inception
                      poster: 14/14017865947c9d3d0d
                      year: 2010
                      status: released
                      ids:
                        simkl: 472214
                        slug: inception
                unknown_id_empty_array:
                  summary: Unknown ID → `200 []` (Type 3 null — NOT a 404)
                  description: >-
                    When no Simkl record matches the supplied ID, the response
                    is `200` with an **empty array** — not a `404`. Apps must
                    inspect array length before reading the first element. Same
                    shape applies when the request has no ID parameters at all.
                  value: []
        '412':
          $ref: '#/components/responses/ClientIdFailed'
        '500':
          $ref: '#/components/responses/ServerError'
      security:
        - clientId: []
      x-codeSamples:
        - lang: Shell
          label: imdb_movie
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?imdb=tt1375666&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: tmdb_movie
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?tmdb=27205&type=movie&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: tmdb_tv
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?tmdb=1399&type=tv&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: tvdb_tv
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?tvdb=153021&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: mal_anime
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?mal=38000&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: simkl_id_roundtrip
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?simkl=472214&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: unknown_id_empty_array
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/search/id?imdb=tt99999999&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
components:
  parameters:
    ClientIdQuery:
      name: client_id
      in: query
      required: true
      description: >-
        Your **`client_id`** from your [Simkl developer
        settings](https://simkl.com/settings/developer/). Required on every
        request.
      schema:
        type: string
      example: YOUR_CLIENT_ID
    AppNameQuery:
      name: app-name
      in: query
      required: true
      description: >-
        Short, lowercase identifier for your app (e.g. `plex-scrobbler`,
        `kodi-bridge`). Helps Simkl identify which apps are using the API.
      schema:
        type: string
      example: my-app
    AppVersionQuery:
      name: app-version
      in: query
      required: true
      description: >-
        Your app's current version (e.g. `1.0`, `2.4.1`). Helps Simkl debug
        issues you report.
      schema:
        type: string
      example: '1.0'
    UserAgentHeader:
      name: User-Agent
      in: header
      required: true
      description: >-
        Descriptive identifier for your app, ideally `name/version`. Examples:
        `PlexMediaServer/1.43.1.10540`, `kodi-simkl/0.9.2`, `MyApp/2.4.1
        (https://myapp.com)`.
      schema:
        type: string
      example: my-app/1.0
  schemas:
    SearchByIdResultItem:
      type: object
      description: >-
        Result item from `GET /search/id`. Returned inside the top-level
        `SearchByIdResponse` array.
      required:
        - type
        - title
        - status
        - ids
      properties:
        type:
          type: string
          enum:
            - movie
            - tv
            - anime
          description: >-
            Catalog category. Determines which detail endpoint to call next
            (`/movies/{id}` vs `/tv/{id}` vs `/anime/{id}`).
        title:
          type: string
          description: >-
            Display title in the canonical (often non-English) form. For an
            English-localized title use the per-type detail endpoint.
        poster:
          type:
            - string
            - 'null'
          description: >-
            Type 4 null — data not on file in that field's slot. See [Null and
            missing values](/conventions/null-values). Poster image path. See
            [Images](/conventions/images) for how to build the URL.
        year:
          type:
            - integer
            - 'null'
          description: >-
            Type 4 null — data not on file in that field's slot. See [Null and
            missing values](/conventions/null-values).
        status:
          type: string
          enum:
            - released
            - upcoming
            - ended
            - aired
            - tba
          description: >-
            Release / airing status. `released` / `upcoming` apply to movies;
            `ended` / `aired` / `tba` apply to TV and anime. Note this enum is
            broader than the closed `{tba, ended, airing}` set the detail
            endpoints (`/tv/{id}`, `/anime/{id}`) use — `/search/id` is built on
            a different code path.
        total_episodes:
          type: integer
          description: >-
            Total episode count. **Omitted for movies** (only present on `type:
            tv` and `type: anime`).
        anime_type:
          $ref: '#/components/schemas/AnimeFormat'
          description: >-
            Only present on `type: anime` items. Distinguishes the anime catalog
            format (`tv`, `movie`, `ova`, `ona`, `special`, `music video`).
        mal:
          type: object
          description: >-
            Only present on `type: anime` items when Simkl has MAL metadata on
            file. `{id, type}` echoes the MyAnimeList record this entry maps to.
          properties:
            id:
              type: integer
              description: MyAnimeList numeric id.
            type:
              type: string
              description: MAL's own type taxonomy (e.g. `tv`, `movie`, `ova`, `special`).
        ids:
          $ref: '#/components/schemas/SearchByIdResultIds'
    AnimeFormat:
      type: string
      enum:
        - tv
        - movie
        - special
        - ova
        - ona
        - music video
      description: >-
        Anime production format. `tv` is the common case; movies, OVAs, ONAs,
        and music videos all surface through the `/anime/*` endpoints with the
        same response shape.
    SearchByIdResultIds:
      type: object
      description: >-
        Identifiers returned inside each `/search/id` result item. The server
        returns ONLY `simkl` and `slug` here — even when you queried by `imdb`,
        `tmdb`, `tvdb`, `mal`, etc., the response does NOT echo the input ID
        back in this block. To get the full canonical external-ID set for the
        matched record, follow up with the per-type detail endpoint ([`GET
        /movies/{simkl}`](/api-reference/simkl/get-movie), [`GET
        /tv/{simkl}`](/api-reference/simkl/get-tv-show), [`GET
        /anime/{simkl}`](/api-reference/simkl/get-anime)) — those carry the full
        ID set.
      required:
        - simkl
        - slug
      properties:
        simkl:
          type: integer
          description: Canonical Simkl id of the matched record.
          example: 472214
        slug:
          type: string
          description: URL slug for `https://simkl.com/<type>/<simkl>/<slug>` deep links.
          example: inception
    ErrorResponse:
      type: object
      description: >-
        Standard error envelope for 4xx and 5xx responses. Branch on `error`
        (machine-readable identifier) — `message`, when present, is
        human-readable guidance and is **not stable across releases**.
      properties:
        error:
          type: string
          description: >-
            Machine-readable error identifier. Stable across responses — use
            this for programmatic branching in client code. Examples:
            `user_token_failed`, `client_id_failed`, `empty_field`,
            `wrong_parameter`, `id_err`, `rate_limit`.
          example: user_token_failed
        code:
          type: integer
          description: >-
            HTTP status code echoed in the body for convenience — same value as
            the response status line. Always an integer.
          example: 401
        message:
          type: string
          description: >-
            Human-readable error guidance. Optional — present on most errors,
            but not guaranteed. May reference the specific field or value that
            triggered the error. NOT stable; do not parse.
          example: Your client_id is wrong. Try another one
      required:
        - error
        - code
  responses:
    ClientIdFailed:
      description: >-
        Your `client_id` is missing, wrong, disabled, or has hit a request
        limit. Verify in your [developer
        settings](https://simkl.com/settings/developer/).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: client_id_failed
            code: 412
            message: Your client_id is wrong. Try another one
    ServerError:
      description: >-
        Something is broken on Simkl's side. Retry after a short delay. If it
        persists, report on the [Simkl Discord](https://discord.gg/MJsWNE4).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: internal
            code: 500
  securitySchemes:
    clientId:
      type: apiKey
      in: query
      name: client_id
      description: >-
        Preferred form: your `client_id` as a URL query parameter on every
        request. Self-describing in logs and curl commands. See [Headers and
        required parameters](/conventions/headers).
      x-default: YOUR_CLIENT_ID
    simklApiKey:
      type: apiKey
      in: header
      name: simkl-api-key
      description: >-
        Optional alias for the `client_id` query parameter. Simkl accepts your
        `client_id` either as the `simkl-api-key` request header **or** as the
        `?client_id=…` query parameter — pick one. The query-parameter form is
        preferred because it makes the request fully self-describing in URL
        form.
      x-default: YOUR_CLIENT_ID

````