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

# Redirect to a user's last-watched cover image

> Pulls metadata about the user's most recently watched item — useful for "Now Watching" widgets, dashboard backgrounds, and embedded user-cards.

PUBLIC endpoint — no `access_token` required, just your `client_id`. The target user's profile must be public; private profiles return `404`.

#### Two response modes (selected by the `image` query param)

| `image` | Status | Body | Use case |
|---|---|---|---|
| _omitted_ | `200` | JSON with `id`, `url`, `title`, `poster`, `fanart` | Server-side render or custom card layout |
| `poster` | `302` | Empty; `Location: https://simkl.net/posters/<key>_0.jpg` | Drop the request URL straight into `<img src=…>` |
| `fanart` | `302` | Empty; `Location: https://simkl.net/fanart/<key>_0.jpg` | Same — full-bleed background image |

#### Drop-in `<img>` example

The `?image=` redirect modes are designed for `<img src="…">` tags. The browser follows the 302 automatically and renders the JPG — no JSON parsing, no string concatenation, no extra requests:

```html
<!-- Background image (1920×1080-ish) -->
<img src="https://api.simkl.com/users/recently-watched-background/12345?image=fanart&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0">

<!-- Cover poster (vertical) -->
<img src="https://api.simkl.com/users/recently-watched-background/12345?image=poster&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0">
```

#### JSON mode shape

The no-param mode returns the same image keys as the redirect modes — concatenate manually if you want to skip the second round-trip:

```json
{
  "id": 17465,
  "url": "https://simkl.com/tv/17465/game-of-thrones",
  "title": "Game of Thrones",
  "poster": "17/17465posterkey",
  "fanart": "17/17465fanartkey"
}
```

Render as `https://simkl.net/posters/<poster>_0.jpg` / `https://simkl.net/fanart/<fanart>_0.jpg`.



## OpenAPI

````yaml /openapi.json get /users/recently-watched-background/{user_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:
  /users/recently-watched-background/{user_id}:
    get:
      tags:
        - Users
      summary: Redirect to a user's last-watched cover image
      description: >-
        Pulls metadata about the user's most recently watched item — useful for
        "Now Watching" widgets, dashboard backgrounds, and embedded user-cards.


        PUBLIC endpoint — no `access_token` required, just your `client_id`. The
        target user's profile must be public; private profiles return `404`.


        #### Two response modes (selected by the `image` query param)


        | `image` | Status | Body | Use case |

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

        | _omitted_ | `200` | JSON with `id`, `url`, `title`, `poster`, `fanart`
        | Server-side render or custom card layout |

        | `poster` | `302` | Empty; `Location:
        https://simkl.net/posters/<key>_0.jpg` | Drop the request URL straight
        into `<img src=…>` |

        | `fanart` | `302` | Empty; `Location:
        https://simkl.net/fanart/<key>_0.jpg` | Same — full-bleed background
        image |


        #### Drop-in `<img>` example


        The `?image=` redirect modes are designed for `<img src="…">` tags. The
        browser follows the 302 automatically and renders the JPG — no JSON
        parsing, no string concatenation, no extra requests:


        ```html

        <!-- Background image (1920×1080-ish) -->

        <img
        src="https://api.simkl.com/users/recently-watched-background/12345?image=fanart&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0">


        <!-- Cover poster (vertical) -->

        <img
        src="https://api.simkl.com/users/recently-watched-background/12345?image=poster&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0">

        ```


        #### JSON mode shape


        The no-param mode returns the same image keys as the redirect modes —
        concatenate manually if you want to skip the second round-trip:


        ```json

        {
          "id": 17465,
          "url": "https://simkl.com/tv/17465/game-of-thrones",
          "title": "Game of Thrones",
          "poster": "17/17465posterkey",
          "fanart": "17/17465fanartkey"
        }

        ```


        Render as `https://simkl.net/posters/<poster>_0.jpg` /
        `https://simkl.net/fanart/<fanart>_0.jpg`.
      operationId: get-users-recently-watched-background-user-id
      parameters:
        - name: user_id
          in: path
          description: Simkl user id which has public privacy settings.
          required: true
          schema:
            type: integer
          example: '51'
        - name: image
          in: query
          description: >-
            Switches the response mode:


            - **Omitted** (no `image` param) → `200` with JSON metadata (`id`,
            `url`, `title`, `poster`, `fanart`).

            - `image=poster` → `302` redirect to the poster JPG on
            `simkl.net/posters/`.

            - `image=fanart` → `302` redirect to the fanart JPG on
            `simkl.net/fanart/`.


            The two redirect modes are designed to drop straight into an `<img
            src="…">` tag — no JSON parsing or string concatenation needed.
          required: false
          schema:
            type: string
            enum:
              - poster
              - fanart
          example: fanart
        - $ref: '#/components/parameters/ClientIdQuery'
        - $ref: '#/components/parameters/AppNameQuery'
        - $ref: '#/components/parameters/AppVersionQuery'
        - $ref: '#/components/parameters/UserAgentHeader'
      responses:
        '200':
          description: >-
            Returned when `?image=` is omitted. JSON metadata about the user's
            most recently watched item.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecentlyWatchedBackground'
              examples:
                metadata_tv:
                  summary: TV show — most recently watched (no `?image=` param)
                  value:
                    id: 17465
                    url: https://simkl.com/tv/17465/game-of-thrones
                    title: Game of Thrones
                    poster: 17/17465posterkey
                    fanart: 17/17465fanartkey
                metadata_movie:
                  summary: Movie — most recently watched
                  value:
                    id: 472214
                    url: https://simkl.com/movies/472214/inception
                    title: Inception
                    poster: 47/472214posterkey
                    fanart: 47/472214fanartkey
                metadata_anime:
                  summary: Anime — most recently watched
                  value:
                    id: 831411
                    url: https://simkl.com/anime/831411/kimetsu-no-yaiba
                    title: 'Demon Slayer: Kimetsu no Yaiba'
                    poster: 83/831411posterkey
                    fanart: 83/831411fanartkey
        '302':
          description: >-
            Returned for `?image=poster` or `?image=fanart`. Body is empty; the
            JPG URL is in the `Location` header. Drop the request URL straight
            into `<img src="…">`; the browser follows the redirect automatically
            and renders the image.
          headers:
            Location:
              description: >-
                Fully-qualified URL of the JPG on `simkl.net`. Format:
                `https://simkl.net/posters/<poster_key>_0.jpg` for
                `?image=poster`, `https://simkl.net/fanart/<fanart_key>_0.jpg`
                for `?image=fanart`.
              schema:
                type: string
                format: uri
              examples:
                fanart:
                  summary: Returned when `?image=fanart`
                  value: https://simkl.net/fanart/17/17465fanartkey_0.jpg
                poster:
                  summary: Returned when `?image=poster`
                  value: https://simkl.net/posters/17/17465posterkey_0.jpg
          content: {}
        '404':
          description: >-
            `user_id` is non-numeric, `0`, or otherwise invalid (the path
            matcher requires a positive integer).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: user_id_failed
                code: 404
        '412':
          $ref: '#/components/responses/ClientIdFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
      security:
        - simklApiKey: []
      x-codeSamples:
        - lang: HTML
          label: Fanart <img> drop-in
          source: >-
            <img
            src="https://api.simkl.com/users/recently-watched-background/12345?image=fanart&client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
            alt="Now watching" />
        - lang: Shell
          label: JSON metadata (no ?image=)
          source: |-
            curl -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/users/recently-watched-background/12345?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"
        - lang: Shell
          label: Follow the 302 to the JPG (-L)
          source: |-
            curl -L -o cover.jpg -H "User-Agent: my-app-name/1.0" \
              "https://api.simkl.com/users/recently-watched-background/12345?image=poster&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:
    RecentlyWatchedBackground:
      type: object
      description: >-
        Metadata about the user's most recently watched item. Returned by `GET
        /users/recently-watched-background/{user_id}` when called WITHOUT the
        `?image=` query param. The `poster` and `fanart` fields are catalog
        image keys (the on-disk path prefix) — to render the actual JPG, either
        call the same endpoint again with `?image=poster` (or `?image=fanart`)
        to get a 302 redirect to the JPG, or concatenate manually:
        `https://simkl.net/posters/<poster>_0.jpg` /
        `https://simkl.net/fanart/<fanart>_0.jpg`.
      required:
        - id
        - url
        - title
      properties:
        id:
          type: integer
          description: Simkl id of the most recently watched item.
          example: 17465
        url:
          type: string
          format: uri
          description: >-
            Canonical `simkl.com/<type>/<id>/<slug>` URL — drop into a card
            heading or share button.
          example: https://simkl.com/tv/17465/game-of-thrones
        title:
          type: string
          description: Display title of the most recently watched item.
          example: Game of Thrones
        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). When present, the poster
            image key (e.g. `"17/17465abcd"`) — render as
            `https://simkl.net/posters/<this>_0.jpg`.
          example: 17/17465posterkey
        fanart:
          type:
            - string
            - 'null'
          description: >-
            Type 4 null — data not on file in that field's slot. See [Null and
            missing values](/conventions/null-values). When present, the fanart
            image key — render as `https://simkl.net/fanart/<this>_0.jpg`.
          example: 17/17465fanartkey
    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
    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

````