Skip to content

Uploading Files To Sanity via API

Sanity/

In Sanity, creating documents and uploading assets is usually done with Sanity Studio via its user interface. But, it can also be done with Sanity’s HTTP API. For example, using its assets endpoint, you can upload files such as images and PDFs straight to your dataset. This can be used when you want to allow your users to upload files when interacting with your web application.

To upload files programmatically to Sanity via its API you will need to write server-side code.

Before you can start, you need to create an access token with write permissions. Then you need to read the file from the request made to your server from your client. And finally, send that file to Sanity using its API.

Setting Up Environment

To upload files to Sanity via its API, you need to set up a few things first.

First, install Sanity’s JavaScript client, which makes it easier to make HTTP requests to Sanity instead doing it manually.

npm install @sanity/client

Next, generate an access token to be able to update your Sanity dataset from code. Here’s how to do it:

  • Log into your sanity.io account and go to your project’s dashboard
  • Navigate to API and scroll down to Tokens
  • Click Add API token
  • Give it a Name you want and pick Editor under Permissions
  • Copy the generated token and keep it as a secret in your code base, it should not be shared publicly
  • If you ever lose this token, you can always come back and generate a new one. Don’t forget to delete the lost one from Sanity project settings in that case

Finally, create a server-side function that can handle incoming HTTP requests and make outgoing ones to Sanity. I will be using Next.js API route for this.

import { createClient } from '@sanity/client';

export async function POST(request: Request): Promise<Response> {
  const client = createClient({
    projectId: process.env.SANITY_PROJECT_ID,
    dataset: process.env.SANITY_DATASET,
    apiVersion: process.env.SANITY_API_VERSION,
    token: process.env.SANITY_ACCESS_TOKEN,
  });

  return new Response();
}

This code handles incoming POST requests to an API route in Next.js and creates a Sanity client instance using environment variables.

Uploading Files to Sanity via API

Now that your project is ready to handle client requests and make them to Sanity’s API, lets handle the file upload.

First, you will need to read the incoming file from the request object sent by your client. Sanity’s API can accept files represented in many interfaces — File, Blob, Buffer or ReadableStream.

Conveniently, Request has a blob method that converts the received body into a Blob.

You can then pass that Blob to Sanity’s client.assets.upload method and it will upload the file to your Sanity dataset.

export async function POST(request: Request): Promise<Response> {
    const client = createClient({
    projectId: process.env.SANITY_PROJECT_ID,
    dataset: process.env.SANITY_DATASET,
    apiVersion: process.env.SANITY_API_VERSION,
    token: process.env.SANITY_ACCESS_TOKEN,
  });

  const blob = await request.blob();

  await client.assets.upload('image', blob, {
    filename: 'image.png',
    contentType: 'image/png',
  });

  return new Response();
}

In this case, it is uploading an image, so the first upload argument must be set to image and the contentType must be specify that. The filename is up to you to change to what you want.

Similarly, you can upload files such as PDF documents with some minor changes.

const blob = await request.blob();

await client.assets.upload('file', blob, {
  filename: 'my-document.pdf',
  contentType: 'application/pdf',
});

If you need a dynamic and a random filename, you can use randomUUID method to generate one for you one.

import { randomUUID } from 'crypto';

export async function POST(request: Request): Promise<Response> {
  // ✂️

  await client.assets.upload('file', blob, {
    filename: `invoice-${randomUUID()}.pdf`,
    contentType: 'application/pdf',
  });

  return new Response();
}