> ## 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.

# Remove from History

> Removes items from the user's watched history. **Body shape is identical to [`POST /sync/history`](/api-reference/simkl/add-to-history)** — the same `movies[]`, `shows[]`, and granularity rules apply.

#### Granularity

What you send determines what gets removed.

**Movie or show with no `seasons` and no `episodes`** — the item is **removed from the user's library entirely** (any watch history AND the watchlist entry). Equivalent to the user clicking "Remove from list" on the title page.

```json
{ "shows": [{ "ids": {...} }] }
```

**Show with `seasons[]` entries that omit `episodes`** — every episode in those seasons is unmarked as watched. The show stays in the user's library.

```json
{ "shows": [{ "ids": {...}, "seasons": [{ "number": 2 }] }] }
```

**Show with `seasons[].episodes[]`** — only the listed episodes are unmarked. The show stays in the user's library.

```json
{
  "shows": [{
    "ids": {...},
    "seasons": [{
      "number": 1,
      "episodes": [{ "number": 1 }, { "number": 2 }]
    }]
  }]
}
```

**Show with top-level `episodes[]` shorthand** — treated as `seasons: [{ number: 1, episodes: [...] }]`. Convenient for single-season shows; otherwise prefer the explicit form.

```json
{ "shows": [{ "ids": {...}, "episodes": [{ "number": 1 }] }] }
```

#### Response shape

Status: **201 Created**.

```json
{
  "deleted": {
    "movies":   <number of movies removed>,
    "shows":    <number of shows removed from library>,
    "episodes": <number of episodes unmarked>
  },
  "not_found": {
    "movies": [<items Simkl could not match>],
    "shows":  [<items Simkl could not match>]
  }
}
```

**`not_found` only has `movies` and `shows`** — there's no `not_found.episodes` array even when you tried to remove specific episodes. If the parent show isn't matchable, the show object lands in `not_found.shows` and no episodes are touched. If the show is matchable but a specific episode number doesn't exist, the call still counts as success and `episodes` in `deleted` reflects only the episodes that were actually unmarked.

**Anime titles** go in `shows[]` (with anime-only IDs like `anidb` / `mal` / `anilist` inside each item's `ids` object). There is no top-level `anime[]` array on this endpoint — items sent under one are silently ignored. See [Anime under shows[]](/conventions/standard-media-objects#anime).

<CardGroup cols={2}>
  <Card title="POST /sync/history" icon="clock" href="/api-reference/simkl/add-to-history" horizontal>
    The mirror endpoint that adds history. Same body shape; this page is the removal side.
  </Card>
  <Card title="Sync guide — full walkthrough" icon="arrows-rotate" href="/guides/sync" horizontal>
    Two-phase model (initial pull → activities-checked delta loop), deletion reconciliation, and reference implementations.
  </Card>
</CardGroup>

<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 post /sync/history/remove
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:
  /sync/history/remove:
    post:
      tags:
        - Sync
      summary: Remove from History
      description: >-
        Removes items from the user's watched history. **Body shape is identical
        to [`POST /sync/history`](/api-reference/simkl/add-to-history)** — the
        same `movies[]`, `shows[]`, and granularity rules apply.


        #### Granularity


        What you send determines what gets removed.


        **Movie or show with no `seasons` and no `episodes`** — the item is
        **removed from the user's library entirely** (any watch history AND the
        watchlist entry). Equivalent to the user clicking "Remove from list" on
        the title page.


        ```json

        { "shows": [{ "ids": {...} }] }

        ```


        **Show with `seasons[]` entries that omit `episodes`** — every episode
        in those seasons is unmarked as watched. The show stays in the user's
        library.


        ```json

        { "shows": [{ "ids": {...}, "seasons": [{ "number": 2 }] }] }

        ```


        **Show with `seasons[].episodes[]`** — only the listed episodes are
        unmarked. The show stays in the user's library.


        ```json

        {
          "shows": [{
            "ids": {...},
            "seasons": [{
              "number": 1,
              "episodes": [{ "number": 1 }, { "number": 2 }]
            }]
          }]
        }

        ```


        **Show with top-level `episodes[]` shorthand** — treated as `seasons: [{
        number: 1, episodes: [...] }]`. Convenient for single-season shows;
        otherwise prefer the explicit form.


        ```json

        { "shows": [{ "ids": {...}, "episodes": [{ "number": 1 }] }] }

        ```


        #### Response shape


        Status: **201 Created**.


        ```json

        {
          "deleted": {
            "movies":   <number of movies removed>,
            "shows":    <number of shows removed from library>,
            "episodes": <number of episodes unmarked>
          },
          "not_found": {
            "movies": [<items Simkl could not match>],
            "shows":  [<items Simkl could not match>]
          }
        }

        ```


        **`not_found` only has `movies` and `shows`** — there's no
        `not_found.episodes` array even when you tried to remove specific
        episodes. If the parent show isn't matchable, the show object lands in
        `not_found.shows` and no episodes are touched. If the show is matchable
        but a specific episode number doesn't exist, the call still counts as
        success and `episodes` in `deleted` reflects only the episodes that were
        actually unmarked.


        **Anime titles** go in `shows[]` (with anime-only IDs like `anidb` /
        `mal` / `anilist` inside each item's `ids` object). There is no
        top-level `anime[]` array on this endpoint — items sent under one are
        silently ignored. See [Anime under
        shows[]](/conventions/standard-media-objects#anime).


        <CardGroup cols={2}>
          <Card title="POST /sync/history" icon="clock" href="/api-reference/simkl/add-to-history" horizontal>
            The mirror endpoint that adds history. Same body shape; this page is the removal side.
          </Card>
          <Card title="Sync guide — full walkthrough" icon="arrows-rotate" href="/guides/sync" horizontal>
            Two-phase model (initial pull → activities-checked delta loop), deletion reconciliation, and reference implementations.
          </Card>
        </CardGroup>


        <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: post-sync-history-remove
      parameters:
        - $ref: '#/components/parameters/ClientIdQuery'
        - $ref: '#/components/parameters/AppNameQuery'
        - $ref: '#/components/parameters/AppVersionQuery'
        - $ref: '#/components/parameters/UserAgentHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HistoryRequest'
            examples:
              remove_movie_entirely:
                summary: Remove a movie from history AND watchlist
                value:
                  movies:
                    - ids:
                        simkl: 53536
              remove_specific_episodes:
                summary: Unmark specific episodes — show stays in library
                value:
                  shows:
                    - ids:
                        simkl: 2090
                      seasons:
                        - number: 1
                          episodes:
                            - number: 1
                            - number: 2
              remove_whole_season:
                summary: >-
                  Unmark every episode in a season — pass season with no
                  episodes
                value:
                  shows:
                    - ids:
                        simkl: 2090
                      seasons:
                        - number: 2
              remove_entire_show:
                summary: Remove the entire show from the user's library
                value:
                  shows:
                    - ids:
                        simkl: 2090
              bulk_mixed:
                summary: 'Bulk: one movie + episodes from one show in a single call'
                value:
                  movies:
                    - ids:
                        simkl: 53536
                  shows:
                    - ids:
                        simkl: 2090
                      seasons:
                        - number: 3
                          episodes:
                            - number: 1
              not_found_unknown_id:
                summary: Unknown ID lands in `not_found` — partial success is normal
                value:
                  movies:
                    - ids:
                        simkl: 99999991
              anime_under_shows:
                summary: Anime title goes in `shows[]` with anime-only IDs
                value:
                  shows:
                    - title: Demon Slayer
                      ids:
                        simkl: 831411
                        mal: 38000
                        anidb: 14116
                        anilist: 101922
        required: true
      responses:
        '201':
          description: Counts of items affected, plus any IDs Simkl could not match.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HistoryRemoveResponse'
              examples:
                remove_movie_entirely:
                  summary: Remove a movie from history AND watchlist
                  value:
                    deleted:
                      movies: 1
                      shows: 0
                      episodes: 0
                    not_found:
                      movies: []
                      shows: []
                remove_specific_episodes:
                  summary: Unmark specific episodes — show stays in library
                  value:
                    deleted:
                      movies: 0
                      shows: 0
                      episodes: 2
                    not_found:
                      movies: []
                      shows: []
                remove_whole_season:
                  summary: >-
                    Unmark every episode in a season — pass season with no
                    episodes
                  value:
                    deleted:
                      movies: 0
                      shows: 0
                      episodes: 13
                    not_found:
                      movies: []
                      shows: []
                remove_entire_show:
                  summary: Remove the entire show from the user's library
                  value:
                    deleted:
                      movies: 0
                      shows: 1
                      episodes: 0
                    not_found:
                      movies: []
                      shows: []
                bulk_mixed:
                  summary: 'Bulk: one movie + episodes from one show in a single call'
                  value:
                    deleted:
                      movies: 1
                      shows: 0
                      episodes: 1
                    not_found:
                      movies: []
                      shows: []
                not_found_unknown_id:
                  summary: Unknown ID lands in `not_found` — partial success is normal
                  value:
                    deleted:
                      movies: 0
                      shows: 0
                      episodes: 0
                    not_found:
                      movies:
                        - ids:
                            simkl: 99999991
                          type: movie
                      shows: []
                anime_under_shows:
                  summary: Anime title goes in `shows[]` with anime-only IDs
                  value:
                    deleted:
                      movies: 0
                      shows: 1
                      episodes: 0
                    not_found:
                      movies: []
                      shows: []
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '412':
          $ref: '#/components/responses/ClientIdFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
      security:
        - clientId: []
          bearerAuth: []
        - simklApiKey: []
          bearerAuth: []
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:
    HistoryRequest:
      type: object
      description: >-
        Body for `/sync/history` and `/sync/history/remove`. Items go under
        `movies[]`, `shows[]`, or `anime[]` — Simkl resolves anime titles
        correctly under either `shows[]` or `anime[]`, so match the field to
        your data type when known.
      properties:
        movies:
          type: array
          items:
            $ref: '#/components/schemas/Movie'
        shows:
          type: array
          items:
            $ref: '#/components/schemas/Show'
        episodes:
          type: array
          description: >-
            Top-level convenience array for marking episode-level history
            without nesting. The server wraps each entry into a synthetic
            single-season show. Each item carries the same shape as items under
            `shows[].seasons[].episodes[]` plus the parent `show` reference.
          items:
            type: object
            additionalProperties: true
        anime:
          type: array
          items:
            $ref: '#/components/schemas/Show'
          description: Array of anime entries (same shape as `shows[]`).
    HistoryRemoveResponse:
      type: object
      description: Counts of items removed plus any IDs Simkl could not match.
      properties:
        deleted:
          type: object
          properties:
            movies:
              type: integer
              description: Number of movies removed from the user's library.
              example: 1
            shows:
              type: integer
              description: >-
                Number of shows removed from the user's library entirely (only
                counts items where you sent the show without
                `seasons`/`episodes`).
              example: 0
            episodes:
              type: integer
              description: >-
                Number of individual episodes unmarked as watched. The parent
                show stays in the user's library.
              example: 4
          required:
            - movies
            - shows
            - episodes
        not_found:
          type: object
          description: >-
            Per-type lists of input items Simkl could not match. **There is no
            `not_found.episodes` array** — even when you targeted specific
            episodes, only the parent movie/show object lands here if the lookup
            failed.
          properties:
            movies:
              type: array
              items:
                type: object
              description: Input movie objects Simkl could not match.
            shows:
              type: array
              items:
                type: object
              description: Input show/anime objects Simkl could not match.
          required:
            - movies
            - shows
      required:
        - deleted
        - not_found
    Movie:
      type: object
      description: >-
        Standard movie object. See the [Standard Media
        Objects](/conventions/standard-media-objects) guide.
      properties:
        title:
          type: string
          example: 'Terminator 3: Rise of the Machines'
        year:
          type: integer
          example: 2003
        ids:
          $ref: '#/components/schemas/Ids'
      required:
        - ids
    Show:
      type: object
      description: >-
        Standard show object. May include nested seasons/episodes for partial
        sync.
      properties:
        title:
          type: string
          example: The Walking Dead
        year:
          type: integer
          example: 2010
        ids:
          $ref: '#/components/schemas/Ids'
        seasons:
          type: array
          items:
            type: object
            properties:
              number:
                type: integer
              episodes:
                type: array
                items:
                  $ref: '#/components/schemas/Episode'
      required:
        - ids
    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
    Ids:
      type: object
      description: >-
        External and internal identifiers for an item. Pass as many as you have
        — Simkl resolves to the canonical record.
      properties:
        simkl:
          type: integer
          description: Simkl internal ID. Most reliable.
          example: 53536
        slug:
          type: string
          description: URL-safe slug returned in responses.
          example: attack-on-titan
        imdb:
          type: string
          description: IMDb ID.
          example: tt0181852
        tmdb:
          type: string
          description: TMDb ID.
          example: '296'
        tvdb:
          oneOf:
            - type: integer
            - type: string
          description: TVDB ID or slug.
          example: 153021
        mal:
          type: string
          description: MyAnimeList ID.
          example: '4246'
        anidb:
          type: string
          description: AniDB ID. Specifying just this is enough for anime lookups.
          example: '10846'
        anilist:
          type: string
          description: AniList ID.
          example: '21'
        kitsu:
          type: string
          description: Kitsu ID.
          example: '12'
        anisearch:
          type: string
          description: aniSearch ID.
          example: '2227'
        animeplanet:
          type: string
          description: Anime-Planet slug.
          example: one-piece
        livechart:
          type: string
          description: LiveChart ID.
          example: '321'
        letterboxd:
          type: string
          description: Letterboxd slug.
          example: the-truman-show
        netflix:
          type: string
          description: Netflix movie ID.
          example: '70210890'
        hulu:
          type: string
          description: Hulu episode ID.
        crunchyroll:
          type: string
          description: Crunchyroll episode ID.
        traktslug:
          type: string
          description: Trakt slug.
          example: john-wick-chapter-4-2023
      additionalProperties: true
      example:
        simkl: 53536
        imdb: tt0181852
        tmdb: 296
    Episode:
      type: object
      description: Episode reference. Use `season` + `number`, or `ids`.
      properties:
        season:
          type: integer
          minimum: 0
          example: 1
        number:
          type: integer
          minimum: 1
          example: 2
        watched_at:
          type: string
          format: date-time
          example: '2014-09-01T09:10:11Z'
          description: ISO-8601 GMT timestamp.
        ids:
          $ref: '#/components/schemas/Ids'
  responses:
    BadRequest:
      description: Bad request — a required field is missing or has the wrong shape.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: empty_field
            code: 400
            message: Missed "to" parameter
    Unauthorized:
      description: >-
        Missing or invalid user access token. Provide a valid `Authorization:
        Bearer <access_token>` header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: user_token_failed
            code: 401
    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
    RateLimited:
      description: >-
        Too many requests in too short a window. Back off and retry with
        exponential backoff — see [Rate limits](/resources/rate-limits) for the
        playbook.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: rate_limit
            code: 429
    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
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        OAuth 2.0 or PIN-flow `access_token`. Required for endpoints that read
        or modify the user's library, scrobble session, ratings, settings, or
        playbacks. See [Authentication](/authentication).
      x-default: YOUR_ACCESS_TOKEN

````