HTTP API Reference

Media Library API reference

HTTP endpoints reference for the Media Library API

The Media Library API lets you programmatically interact with assets in your organization’s Media Library.

Authentication

  • All requests to private data must be authenticated. Requests to public information, like public assets, are available without an authentication token.
  • Manipulating documents requires read+write access permission for Media Library.

Base API server URL

Media Library API base URL

https://api.sanity.io/{apiVersion}

Variables

  • apiVersionstringdefault: "v2025-02-19"

    API version

Endpoints

Mutate media in the Media Library

post/media-libraries/{libraryId}/mutate

You can use this endpoint to create, update, or delete documents in the Media Library. This uses the same mutation syntax as Content Lake's Mutation API.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Query parameters

  • dryRunbooleandefault: false

    Validate the mutations and return the result without saving any changes.

Request body application/json

  • mutationsarrayrequired
    Show child attributes
    items
    • createobject

      Create a document. Fails if a document with the same _id exists.

      Show child attributes
    • Create a document only if no document with the same _id exists.

      Show child attributes
    • Create a document, or replace the existing document with the same _id.

      Show child attributes
    • deleteobject

      Delete the document with the given id.

      Show child attributes
      • idstringrequired
    • Show child attributes

Responses

200

Mutation successful

  • transactionIdstringrequired

    ID of the transaction

  • resultsarrayrequired
    Show child attributes
    items
    • idstring
    • operationstring

      The operation performed, such as create, update, or delete

Examplesapplication/json
{
  "transactionId": "2ytbpDyMzSFDiMWMZQvN1i",
  "results": [
    {
      "id": "image-123",
      "operation": "update"
    }
  ]
}

Query media in the Media Library

get/media-libraries/{libraryId}/query

Use GROQ to query the Media Library.

Requests without a token are allowed, but return only data that is publicly readable. On a private library they return an empty result rather than an error.

See the GROQ documentation for more information on writing GROQ queries.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Query parameters

  • querystringrequired
    assets:*[_type == "sanity.asset"]
    aspects:*[_type == "sanity.asset.aspect"]
    projections:*[_type == "sanity.asset"] { _id, _type, title }

Responses

200

OK

  • querystring

    The GROQ query and projection executed against the Media Library.

  • resultstring|number|boolean|array|object|null

    The result of the query. The type of the result depends on the query response.

    For example, if the query returns a single document, the result will be an object. If it returns a list of documents, the result will be an array.

  • A list of sync tags. Sync tags are used with the Live Content API to track document changes.

    Show child attributes
    items
    • string
  • msnumber

    Server-side query time in milliseconds

Query media in the Media Library with a request body

post/media-libraries/{libraryId}/query

Same as the GET endpoint, with the query sent in a JSON body. Use this for long queries.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Request body application/json

  • querystringrequired

    The GROQ query and projection to execute against the Media Library.

  • paramsobject

    Values for $-prefixed parameters used in the query.

Examplesapplication/json
{
  "query": "*[_type == \"sanity.asset\" && title match $term]{_id, title}",
  "params": {
    "term": "chair"
  }
}

Responses

200

OK. Same response body as the GET endpoint.

  • object

List references to an asset

get/media-libraries/{libraryId}/references/documents/{assetId}/to

Get references to an asset document from other documents and datasets. At this time, this does not support draft or version documents.

Note: this endpoint is currently only available on version vX of the API. Requests on dated API versions return 400.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • assetIdstringrequired

    The ID of the asset to get references for.

Query parameters

  • cursorstring

    A cursor to paginate through the results. The cursor is returned in the nextCursor field of the response.

  • excludePathsbooleandefault: false

    When true, sourceFieldPaths is returned as an empty array.

  • perspectivestringdefault: "published"

    Only published is supported. Any other value returns 400.

Responses

200

OK

  • Show child attributes
    items
    • The global document reference ID of the document that references the asset.

      This is made up of {resourceType}:{resourceId}:{documentId}. For datasets, the resource ID is {projectId}.{dataset}.

      Example:dataset:y3d2bw.production:document-id1234
    • A list of field path locations in the document that reference the asset.

      Example
      ["mainImage.media._ref","body[4].media._ref"]
      Show child attributes
      items
      • string
  • totalCountinteger

    Number of references in this page of results. Pages hold at most 100 references.

  • Cursor for the next page of results. It can be returned even when no more results exist, so keep requesting pages until the response has no nextCursor.

Examplesapplication/json
{
  "references": [
    {
      "sourceDocumentRef": "dataset:y856rro4.production:196167ef-8c0b-4d7c-ae18-71179e424c19",
      "sourceFieldPaths": [
        "mainImage.media._ref"
      ]
    },
    {
      "sourceDocumentRef": "dataset:y856rro4.production:503cceed-a1b5-4552-9cc1-c6fddf28de59",
      "sourceFieldPaths": [
        "body[4].media._ref"
      ]
    },
    {
      "sourceDocumentRef": "dataset:y856rro4.production:drafts.196167ef-8c0b-4d7c-ae18-71179e424c19",
      "sourceFieldPaths": [
        "gdrImage._ref",
        "mainImage.media._ref"
      ]
    }
  ],
  "totalCount": 3,
  "nextCursor": "gdr1:eyJucyI6Ink4NTZycm80LnByb2R1Y3Rpb24uS2RSS2c4Z0tJQVFhIiwiaWQiOiJkcmFmdHMuMTk2MTY3ZWYtOGMwYi00ZDdjLWFlMTgtNzExNzllNDI0YzE5In0"
}

Upload an asset to the media library

post/media-libraries/{libraryId}/upload

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Query parameters

  • typestring

    Type of asset being uploaded. If omitted, the type is detected from the file content.

  • filenamestring

    Original filename

  • titlestring

    Asset title. Cannot be combined with autoGenerateTitle. If omitted and filename is provided, the filename is used as the initial title.

  • Generate a title from image content during image processing. Cannot be combined with title, even when set to false.

  • assetIdstring

    Existing asset ID to add a new version to. Omit to create an asset. The upload must be the same asset type as the existing asset, and cannot be combined with an aspects part.

  • sessionIdstring

    Upload session identifier. Must not be empty.

  • CDN access policy. When assetId is set, defaults to the existing asset's policy, and a different value returns 400.

  • sha1string

    SHA-1 hash of the file. If an asset with this hash already exists, the request returns 409. Otherwise, the uploaded content is checked against the hash and a mismatch returns 400.

  • parentstring

    Document ID of the sanity.directory to place the uploaded asset in. If omitted, the uploaded asset is not placed in a folder. Must reference a sanity.directory, sanity.tree is not a valid value.

  • Document ID of the root sanity.directory for the uploaded asset. Requires parent to also be set.

Request body multipart/form-data

  • aspectsobject

    Optional JSON object of aspect values to set on the asset at creation. JSON null is accepted and treated as equivalent to omitting the field. Capped at 1 MiB; larger payloads return 400.

  • filestring (binary)required

    The asset file to upload. Must be the last part in the multipart body — any parts after file are not read, because the file's reader is consumed lazily by the upload pipeline.

Other content types: application/octet-stream

Responses

200

Asset uploaded successfully

  • assetobjectrequired
    Show child attributes
  • assetInstanceobjectrequired

    Asset instance with metadata

  • uploadSessionobject|nullrequired

    Upload session information, or null when no upload session is returned.

Search for assets and references

get/media-libraries/{libraryId}/refsearch

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Query parameters

  • termstringrequired

    Search term

  • filterstring

    GROQ filter expression, combined with the search using AND.

  • GROQ projection for each result. Include _id, or nextCursor is never returned.

  • perspectivestringdefault: "published"

    Perspective to search. Use published, preview, raw, or a release name.

  • cursorstring

    The nextCursor value from the previous page. Results are ordered by _id descending.

  • limitintegerdefault: 10

    Maximum number of results to return

Responses

200

Search results

  • resultsrequired

    The matching documents, shaped by projection

  • nextCursorstring|nullrequired

    Cursor for the next page, or null when the page isn't full or results have no _id

  • countintegerrequired

    Number of results in this page

Create a new signing key

post/media-libraries/{libraryId}/signing-keys

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Request body application/json

  • namestringrequired

    Name of the signing key. Letters, numbers, spaces, hyphens, and underscores only.

  • keyTypestringdefault: "ed25519"

    Type of signing key

Responses

200

Signing key created successfully

  • idstringrequired

    Signing key ID

  • namestringrequired

    Signing key name

  • publicKeystringrequired

    Public key

  • keyTypestringrequired

    Key type

  • privateKeystringrequired

    Private key (returned only once)

  • statusstringrequired

    Status of the signing key

  • createdAtstring|null (date-time)required

    Creation timestamp

  • updatedAtstring|null (date-time)required

    Last update timestamp. null on create.

  • revokedAtstring|null (date-time)required

    Revocation timestamp. null on create.

List all signing keys

get/media-libraries/{libraryId}/signing-keys

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Responses

200

List of signing keys

  • keysarrayrequired
    Show child attributes
    items
    • idstringrequired

      Signing key ID

    • namestringrequired

      Signing key name

    • keyTypestringrequired

      Key type

    • publicKeystringrequired

      Public key

    • statusstringrequired

      Status of the signing key

    • createdAtstring|null (date-time)

      Creation timestamp

    • updatedAtstring|null (date-time)

      Last update timestamp

    • revokedAtstring|null (date-time)

      Revocation timestamp, or null if the key is active

Get a specific signing key

get/media-libraries/{libraryId}/signing-keys/{keyId}

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • keyIdstringrequired

    Signing key identifier

Responses

200

Signing key details

  • idstringrequired

    Signing key ID

  • namestringrequired

    Signing key name

  • keyTypestringrequired

    Key type

  • publicKeystringrequired

    Public key

  • statusstringrequired

    Status of the signing key

  • createdAtstring|null (date-time)

    Creation timestamp

  • updatedAtstring|null (date-time)

    Last update timestamp

  • revokedAtstring|null (date-time)

    Revocation timestamp, or null if the key is active

Revoke a signing key

delete/media-libraries/{libraryId}/signing-keys/{keyId}

Revokes the signing key. The key isn't removed; it's still returned by the get and list endpoints with status set to revoked.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • keyIdstringrequired

    Signing key identifier

Responses

200

Signing key revoked successfully

Get video playback information

get/media-libraries/{libraryId}/video/{videoId}/playback-info

Public videos don't need a token. Videos with signed playback require a bearer token; without one, the request returns 404.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID. If a container ID is provided, resolves to the current version.

Query parameters

  • Thumbnail width in pixels

  • Thumbnail height in pixels

  • Time in seconds of the frame to use for the thumbnail

  • How the thumbnail fits the requested width and height

  • thumbnailFormatstringdefault: "webp"

    Thumbnail image format

  • Animated image width in pixels

  • Animated image height in pixels

  • Start time in seconds for the animated image

  • End time in seconds for the animated image

  • Frame rate of the animated image

  • animatedFormatstringdefault: "webp"

    Animated image format

  • storyboardFormatstringdefault: "webp"

    Storyboard image format

  • subtitlesFormatstringdefault: "vtt"

    Format for subtitle URLs

  • How long signed playback URLs stay valid, as a duration string such as 90s, 30m, or 2h. Only applies to videos with signed playback. Defaults to the video's duration plus a buffer.

    Example:2h

Responses

200

Video playback information

  • idstringrequired

    Playback ID of the video

  • thumbnailobjectrequired
    Show child attributes
    • urlstring (uri)required

      Playback URL

    • tokenstring

      Access token if required

    • expires_atstring (date-time)

      Expiration timestamp

  • animatedobjectrequired
    Show child attributes
    • urlstring (uri)required

      Playback URL

    • tokenstring

      Access token if required

    • expires_atstring (date-time)

      Expiration timestamp

  • storyboardobjectrequired
    Show child attributes
    • urlstring (uri)required

      Playback URL

    • tokenstring

      Access token if required

    • expires_atstring (date-time)

      Expiration timestamp

  • streamobjectrequired
    Show child attributes
    • urlstring (uri)required

      Playback URL

    • tokenstring

      Access token if required

    • expires_atstring (date-time)

      Expiration timestamp

  • durationnumberrequired

    Video duration in seconds

  • aspectRationumber|null

    Video aspect ratio, or null if unknown

  • Available subtitle tracks

    Show child attributes
    items
    • trackIdstringrequired

      Provider track ID

    • languageCodestringrequired

      ISO 639-1 language code

    • closedCaptionsbooleanrequired

      Whether this track represents closed captions

    • urlstring (uri)required

      URL to the subtitle file

    • tokenstring

      Access token for signed URLs

    • expiresAtstring (date-time)

      Token expiration timestamp

  • Available downloadable MP4 renditions

    Show child attributes
    items
    • urlstring (uri)required

      URL to the rendition redirect endpoint

    • resolutionstringrequired

      Rendition resolution (e.g., "720p", "1080p")

    • tokenstring

      Access token for signed URLs

    • expiresAtstring (date-time)

      Token expiration timestamp

Get video playback information headers

head/media-libraries/{libraryId}/video/{videoId}/playback-info

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID. If a container ID is provided, resolves to the current version.

Responses

200

Video playback information headers

Redirect to video playback URL

get/media-libraries/{libraryId}/video/{videoId}/playback/{type}

Redirects to the playback URL for the given resource type. Accepts the same query parameters as the playback-info endpoint, which shape the redirect target (for example, thumbnail size). Public videos don't need a token. Videos with signed playback require a bearer token; without one, the request returns 404.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID. If a container ID is provided, resolves to the current version.

  • typestringrequired

    Type of playback resource

Query parameters

  • Thumbnail width in pixels

  • Thumbnail height in pixels

  • Time in seconds of the frame to use for the thumbnail

  • How the thumbnail fits the requested width and height

  • thumbnailFormatstringdefault: "webp"

    Thumbnail image format

  • Animated image width in pixels

  • Animated image height in pixels

  • Start time in seconds for the animated image

  • End time in seconds for the animated image

  • Frame rate of the animated image

  • animatedFormatstringdefault: "webp"

    Animated image format

  • storyboardFormatstringdefault: "webp"

    Storyboard image format

  • subtitlesFormatstringdefault: "vtt"

    Format for subtitle URLs

  • How long signed playback URLs stay valid, as a duration string such as 90s, 30m, or 2h. Only applies to videos with signed playback. Defaults to the video's duration plus a buffer.

    Example:2h

Responses

302

Redirect to playback URL

Get playback redirect headers

head/media-libraries/{libraryId}/video/{videoId}/playback/{type}

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID. If a container ID is provided, resolves to the current version.

  • typestringrequired

    Type of playback resource

Responses

302

Redirect headers

Redirect to video rendition URL

get/media-libraries/{libraryId}/video/{videoId}/renditions/{name}

Returns a redirect to the rendition (downloadable MP4) for the specified video. The signed redirect URL is valid for one hour. Public videos don't need a token. Videos with signed playback require a bearer token; without one, the request returns 404.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID. If a container ID is provided, resolves to the current version.

  • namestringrequired

    Rendition name (e.g., "720p.mp4", "1080p.mp4")

Query parameters

  • dlstring

    Download trigger. Boolean true uses rendition name as filename, string value uses as custom filename.

Responses

302

Redirect to rendition URL

Get video rendition redirect headers

head/media-libraries/{libraryId}/video/{videoId}/renditions/{name}

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID. If a container ID is provided, resolves to the current version.

  • namestringrequired

    Rendition name (e.g., "720p.mp4", "1080p.mp4")

Responses

302

Redirect headers

Generate subtitles using AI

post/media-libraries/{libraryId}/video/{videoId}/subtitles

Triggers AI-powered subtitle generation for the specified video. Returns immediately with a processing status; the subtitle will be updated via webhook when generation completes. Requires the organization to have AI features enabled; returns 400 if they are disabled for the org.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID

Request body application/json

  • languageCodestringrequired

    Language code for the generated subtitles, or auto for auto-detection. Only these languages are supported for generation.

Responses

202

Subtitle generation started

  • idstringrequired

    Subtitle document ID

  • languageCodestringrequired

    ISO 639-1 language code

  • closedCaptionsbooleanrequired

    Whether this subtitle represents closed captions

  • statusstringrequired

    Current processing status

  • originstring

    How the subtitle was created

Upload a subtitle file

post/media-libraries/{libraryId}/video/{videoId}/subtitles/upload

Uploads a VTT or SRT subtitle file for the specified video. The subtitle file content is sent as the raw request body (not JSON). Metadata is passed via query parameters. If format is omitted, content starting with WEBVTT is treated as VTT and anything else as SRT. Empty or unparseable content returns 400.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID

Query parameters

  • languageCodestringrequired

    ISO 639-1 two-letter language code (e.g., "en", "fr")

  • formatstring

    Subtitle format. Auto-detected from content if omitted.

  • Whether this subtitle track represents closed captions (includes non-speech audio descriptions)

Request body text/plain

  • string

    Raw subtitle file content (VTT or SRT)

Other content types: application/octet-stream

Responses

202

Subtitle upload accepted

  • idstringrequired

    Subtitle document ID

  • languageCodestringrequired

    ISO 639-1 language code

  • closedCaptionsbooleanrequired

    Whether this subtitle represents closed captions

  • statusstringrequired

    Current processing status

  • originstring

    How the subtitle was created

Delete a subtitle

delete/media-libraries/{libraryId}/video/{videoId}/subtitles/{subtitleId}

Deletes the specified subtitle and its associated track from the video provider.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9
  • videoIdstringrequired

    Video asset instance ID or asset container ID

  • subtitleIdstringrequired

    Subtitle document ID

Responses

204

Subtitle deleted successfully

Upload an asset to the media library from a URL

post/media-libraries/{libraryId}/from-url

Fetches a public or preauthorized HTTPS URL through Sanity's bounded egress proxy, then processes the response with the ordinary Media Library upload pipeline. The source is limited to 50 MiB and the fetch may take up to 300 seconds. Caller credentials and headers are not forwarded to the source. Provide filename in the JSON request body; the filename query parameter used by /upload is not accepted here.

Follows up to three redirects. The source and each redirect destination must use HTTPS without embedded credentials and pass the source policy. The JSON request body is limited to 1 MiB plus 4 KiB, including aspects.

The request stays open while the asset is fetched and uploaded. Allow more than 300 seconds for the client request. Media processing can continue after the response. If the connection closes or the request times out, check the library before retrying: an asset or version may already have been created.

Path parameters

  • libraryIdstringrequired

    Media library identifier

    Example:mlAbC123xYz9

Query parameters

  • typestring

    Optional asset type override. If omitted, the type is detected from the source content.

  • titlestring

    Asset title. Cannot be combined with autoGenerateTitle. If omitted and filename is provided, the filename is used as the initial title.

  • Generate a title from image content during image processing. Cannot be combined with title, even when set to false.

  • assetIdstring

    Existing asset ID to add a version to. Omit to create an asset. Cannot be combined with an aspects object.

  • sessionIdstring

    Upload session identifier. Must not be empty.

  • CDN access policy. When assetId is set, defaults to the existing asset's policy, and a different value returns 400.

  • sha1string

    SHA-1 hash of the file. If an asset with this hash already exists, the request returns 409. Otherwise, the uploaded content is checked against the hash and a mismatch returns 400.

  • parentstring

    Document ID of the sanity.directory to place the uploaded asset in. If omitted, the uploaded asset is not placed in a folder. Must reference a sanity.directory, sanity.tree is not a valid value.

  • Document ID of the root sanity.directory for the uploaded asset. Requires parent to also be set.

Request body application/json

  • urlstring (uri)required

    Public or preauthorized HTTPS source URL

  • filenamestring

    Optional original filename. It is not inferred from the URL.

  • aspectsobject|null

    Optional JSON object of aspect values to set on the asset at creation. JSON null is equivalent to omitting the field. Capped at 1 MiB. Cannot be combined with the assetId query parameter.

Examplesapplication/json
{
  "url": "https://example.com/photos/chair.jpg",
  "filename": "chair.jpg"
}

Responses

200

Asset uploaded successfully

  • assetobjectrequired
    Show child attributes
  • assetInstanceobjectrequired

    Asset instance with metadata

  • uploadSessionobject|nullrequired

    Upload session information, or null when no upload session is returned.