ūüĒģ Sanity Create is here. Writing is reinvented. Try now, no developer setup


Sanity provides extensible UI for managing assets, and an API for dealing with storage, resizing and deletion.

Files, like JPGs and PDFs, which exist alongside your data, are considered assets. The Sanity Studio provides a hassle-free UI for uploading assets, and an unsurprising API for dealing with all asset concerns such as storage, resizing and deletion.

Asset types

We currently support image and file types. image is used for all kinds of images, including SVGs, and file is used for all other file types such as documents, audio files, zip or the like. In the future, we might provide specific support for audio and video files, but currently all non-image files belong in the file category.


Though Sanity lets you import a wide range of image formats like TIFF and SVG our currently supported image formats for processed output are: JPEG, PNG and WebP.

GIF and SVG pass through the image pipeline untouched, but if you want them scaled they will need to be output as one of the three formats above.

To upload assets, use the /assets/images/<dataset> endpoint. Once you have the image URL you can request resized versions of the original image by appending query parameters.

See the Presenting Images documentation for more details.


When you need to upload a non-image file (say a PDF or a zip file) use the /assets/files/<dataset> endpoint. The response is similar to the one you get from an image, but the type will be fileAsset.

Upload an asset

In some cases, uploading assets using the UI is impractical. Say you want to upload a ton of images. If so, you'll want to use the assets API directly.

To upload an image, do a POST request to


with your file in the request body. E.g.:

curl \
  -X POST \
  -H 'Content-Type: image/jpeg' \
  --data-binary "@/Users/mike/images/bicycle.jpg" \
import {createClient} from '@sanity/client'
import {basename} from 'path'
import {createReadStream} from 'fs'

const client = createClient({
  projectId: 'myProjectId',
  dataset: 'myDatasetName',
  apiVersion: '2021-08-29',
  token: 'myToken'

const filePath = '/Users/mike/images/bicycle.jpg'

  .upload('image', createReadStream(filePath), {
    filename: basename(filePath)
  .then(imageAsset => {
    // Here you can decide what to do with the returned asset document. 
    // If you want to set a specific asset field you can to the following:
    return client
        theImageField: {
          _type: 'image',
          asset: {
            _type: "reference",
            _ref: imageAsset._id
  .then(() => {

Example of returned asset document

  "_id": "image-abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538-jpg",
  "_type": "sanity.imageAsset", // type is prefixed by sanity schema
  "assetId": "0G0Pkg3JLakKCLrF1podAdE9",
  "path": "images/myproject/mydataset/abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538.jpg",
  "url": "https://cdn.sanity.io/images/myproject/mydataset/abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538.jpg",
  "originalFilename": "bicycle.jpg",
  "size": 2097152, // File size, in bytes
  "metadata": {
    "dimensions": {
      "height": 538,
      "width": 538,
      "aspectRatio": 1.0
    "location":{ // only present if the original image contained location metadata
      "lat": 59.9241370,
      "lon": 10.7583846,
      "alt": 21.0

Downloading an asset

In order to download an asset from your front-end you need to append ?dl=<asset-of-your-choice.jpg> to the asset URL. If you leave the filename blank, the original filename will be used if present. If the original filename is not available, the id of the file will be used instead.

// GROQ query

*[_type == "post"] {
// Then you can use the URL in HTML for example like this:
// <a href={`${mainImage}?dl=`}>Hero Image</a>

Deleting assets

Deleting an asset can be performed by deleting the associated asset document.

import {createClient} from '@sanity/client'
const config = {
  projectId: 'myProjectID',
  dataset: 'mydataset',
  apiVersion: '2021-08-29',
  token: 'myToken'
const client = createClient(config)
  .then(result => {
    console.log('deleted image asset', result)

It's important to note that while the file is deleted, the CDN might have your asset cached so it may not disappear immediately.

Was this article helpful?