👀 Our most exciting product launch yet 🚀 Join us May 8th for Sanity Connect

Projects API

Manage your Sanity projects using the HTTP API.

The Projects API lets you manage all your Sanity projects, including their CORS origins, datasets, roles, and tags. All requests have to be authenticated. The base URL is https://api.sanity.io.

List all projects

GET /v2021-06-07/projects

Returns a list of all projects you are a member of. The projects are ordered by creation date, with the oldest projects appearing first.

Example

Request

curl --request GET \
  --url 'https://api.sanity.io/v2021-06-07/projects' \
  -H 'Authorization: Bearer <token>'

Response

[
  {
    "id": "54n1ty10",
    "displayName": "My Sanity Project",
    "studioHost": null,
    "organizationId": null,
    "metadata": {
      "color": "#c7494b"
    },
    "isBlocked": false,
    "isDisabled": false,
    "isDisabledByUser": false,
    "activityFeedEnabled": true,
    "createdAt": "2021-05-08T12:09:53.563Z",
    "members": [
      {
        "id": "p-rbzaPneUhfNp",
        "createdAt":"2022-04-26T07:56:31.173Z",
        "updatedAt":"2022-04-26T07:56:31.173Z",
        "isCurrentUser":false,
        "isRobot": true,
        "roles": [
          {
            "name": "viewer",
            "title": "Viewer",
            "description": "Read access to all datasets, with limited access to project settings. (Tokens: read-only)"
          }  
        ]
      },
      {
        "id": "p6yJeps3h",
        "createdAt":"2021-05-08T12:09:53.563Z",
        "updatedAt":"2021-05-08T12:09:53.563Z",
        "isRobot": false,
        "isCurrentUser": true,
        "roles": [
          {
            "name": "administrator",
            "title": "Administrator",
            "description": "Read and write access to all datasets, with full access to all project settings."
          }  
        ]
      }
    ]
  }
]

Create a project

POST /v2021-06-07/projects

Creates a new Sanity project.

Parameters

  • REQUIREDdisplayNamestring

    The display name of your project.

  • organizationIdstring

    Assign the created project to the specified organization. The organization to which organizationId belongs must already exist and you must have sufficient permissions to assign a project to the organization. If omitted, the project is assigned to your personal account.

Example

Request

curl --request POST \
  --url 'https://api.sanity.io/v2021-06-07/projects' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "displayName": "My Sanity Project"
  }'

Response

{
  "isBlocked": false,
  "isDisabled": false,
  "isDisabledByUser": false,
  "metadata": {},
  "maxRetentionDays": null,
  "dataClass": null,
  "activityFeedEnabled": true,
  "id": "54n1ty10",
  "displayName": "My Sanity Project",
  "organizationId": null,
  "updatedAt": "2021-05-08T11:22:17.999Z",
  "createdAt": "2021-05-08T11:22:17.999Z",
  "studioHost": null,
  "deletedAt": null,
  "members": [
    {
      "id": "pModkh5Yq7",
      "role": "administrator",
      "roles": [
        {
          "name": "administrator",
          "title": "Administrator",
          "description": "Administrate projects"
        }
      ]
    }
  ]
}

Retrieve a project

GET /v2021-06-07/projects/:projectId

Returns the details of the existing project :projectId. Provide a unique project ID and the endpoint will retrieve the corresponding project information.

Example

Request

curl  --request GET \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10' \
  -H 'Authorization: Bearer <token>'

Response

{
  "id": "54n1ty10",
  "displayName": "My Sanity Project",
  "studioHost": null,
  "isBlocked": false,
  "isDisabled": false,
  "isDisabledByUser": false,
  "metadata": {},
  "maxRetentionDays": 3,
  "activityFeedEnabled": true,
  "createdAt": "2022-05-02T12:09:53.563Z",
  "updatedAt": "2022-05-02T12:13:49.191Z",
  "organizationId": null,
  "members": [
    {
      "id": "p-pbkazNehPGlp",
      "createdAt": "2022-05-02T12:10:18.010Z",
      "updatedAt": "2022-05-02T12:10:18.010Z",
      "isCurrentUser": true,
      "isRobot": false,
      "roles": [
        {
          "name": "administrator",
          "title": "Administrator",
          "description": "Read and write access to all datasets, with full access to all project settings."
        }
      ]
    }
  ],
  "features": [
    "noVersionRevival",
    "privateDataset",
    "roleEditorRobots",
    "roleViewer"
  ],
  "pendingInvites": 0
}

Update a project

PATCH /v2021-06-07/projects/:projectId

Updates a specific project :projectId with the values of the parameters passed. Any parameters not provided will be left unchanged.

Parameters

  • displayNamestring

    The display name of your project.

  • studioHoststring

    Your studio hostname for deployment on Sanity's hosted service: https://<hostname>.sanity.studio/.

  • metadataobject

    A set of additional configuration options, including:

    • color - a hex value to distinguish your project on sanity.io/manage.
    • externalStudioHost - set this to a URL if you host your Studio outside of Sanity.
  • isDisabledByUserboolean

    Archives your project when set to true. Reactivates your project when set to false.

  • activityFeedEnabledboolean

    Enables the activity feed at sanity.io/manage when set to true. Disables the activity feed when set to false.

Example

Request

curl --request PATCH \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
	  "metadata": {
	    "color": "#c7494b"
	  }
  }'

Response

{
    "id": "54n1ty10",
    "displayName": "My Sanity Project",
    "studioHost": null,
    "isBlocked": false,
    "isDisabled": false,
    "isDisabledByUser": false,
    "metadata": {
        "color": "#c7494b"
    },
    "maxRetentionDays": 3,
    "dataClass": "normal",
    "activityFeedEnabled": true,
    "createdAt": "2022-05-05T12:09:53.563Z",
    "updatedAt": "2022-05-05T12:13:49.191Z",
    "deletedAt": null,
    "organizationId": null,
    "createdByUserId": "grfwFqjIy"
}

Delete a project

DELETE /v2021-06-07/projects/:projectId

Deletes a specific project :projectId.

Gotcha

Use this endpoint with caution. Deleting your project is an irreversible action. There will be no confirmation prompt.

You may want to export all your data beforehand.

Example

Request

curl --request DELETE \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10' \
  -H 'Authorization: Bearer <token>'

Response

{
  "deleted": true
}

List all CORS entries

GET /v2021-06-07/projects/:id/cors

Returns a list of all CORS origins allowed to access the API for this project.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/cors' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

[
  {
    "id": 110863,
    "origin": "http://localhost:3333",
    "allowCredentials": true,
    "createdAt": "2020-05-08T12:09:53.576Z",
    "updatedAt": "2020-05-08T12:09:53.576Z",
    "projectId": "54n1ty10"
  }
]

Create a CORS entry

POST /v2021-06-07/projects/:id/cors

Allows a new origin to use your project API through CORS. Read about browser security and CORS.

Parameters

  • REQUIREDoriginurl

    The origin you want to allow traffic from, stating explicitly the protocol, host name and port. Wildcards (*) are allowed. Use the following format: protocol://host:port.

  • allowCredentialsboolean

    Let the origin send credentials (e.g. a session cookie or an authorization token). Defaults to true.

Example

Request

curl POST 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/cors' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
	"origin": "https://localhost:3333",
	"allowCredentials": false
}'

Response

{
  "id": 112762,
  "projectId": "54n1ty10",
  "origin": "https://localhost:3333",
  "allowCredentials": false,
  "updatedAt": "2020-05-12T18:19:50.102Z",
  "createdAt": "2020-05-12T18:19:50.102Z"
}

Delete a CORS entry

DELETE /v2021-06-07/projects/:id/cors/:id

Deletes an existing CORS origin from your project.

Example

Request

curl DELETE 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/cors/110882' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

{
  "id": 110882,
  "deleted": true
}

List all datasets

GET /v2021-06-07/projects/:id/datasets

Returns a list of all datasets available to a project.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

[
  {
    "name": "production",
    "aclMode": "public"
  }
]

Create a dataset

PUT /v2021-06-07/projects/:id/datasets/:name

Creates a new dataset for your project.

Parameters

  • aclModestring

    Set the visibility of the dataset to either public or private. Defaults to public.

Example

Request

curl PUT 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets/staging' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
	"aclMode": "private"
}'

Response

{
  "datasetName": "staging",
  "aclMode": "private"
}

Copy a dataset

PUT /v2021-06-07/projects/:id/datasets/:id/copy

Enterprise Feature: Copies a dataset inside Sanity's infrastructure

Parameters

  • REQUIREDtargetDatasetstring

    A string containing the name for the new dataset

  • skipHistoryboolean

    If true, revision history is not copied, which will usually result in a much faster copy.

    If false or omitted, revision history is copied to targetDataset.

  • aclModestring

    Property to set ACL mode on target dataset. It accepts one of public, private, or custom.

Example

Gotcha

The copy endpoint is available on Business and Enterprise plans.

Request

curl --location --request PUT 'https://api.sanity.io/v2021-06-07/projects/<project-id>/datasets/<dataset-name>/copy' \
  -H 'Authorization: Bearer <token-here>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "targetDataset": "production-copy"
  }'

Response

{
    "datasetName": "production",
    "message": "Starting copying dataset production to production-copy...",
    "aclMode": "public",
    "jobId": "jobIdString"
}

Delete a dataset

DELETE /v2021-06-07/projects/:id/datasets/:id

Deletes an existing dataset within your project.

Gotcha

Tread carefully when using this endpoint. Deleting your dataset is an irreversible action. You may want to export your dataset beforehand.

Example

Request

curl DELETE 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets/staging' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

{
  "deleted": true
}

List jobs history

Public API for returning list of copy jobs

GET /v2022-04-01/projects/:projectId/datasets/copy?offset=:offset&limit=:limit&state=:state

  • REQUIREDprojectIdstring

    Unique ID of your project

  • offsetnumber

    Start position in list. Default: 0

  • limitnumber

    Max return size. Default: 10

  • statearray

    Comma separated list of job states (pending, running, completed, terminating, terminated, failed). Default: empty.

Example

Request

curl  --request GET \
  --url '/v2022-04-01/projects/5ani7y/datasets/copy?offset=10&limit=100&state=pending,running' \
  -H 'Authorization: Bearer <token>'

Response

// Array of JSON objects for each job returned
[
{
    "id": "jacsfsmnxp",
    "state": "running",
    "authors": [
        "authorId"
    ],
    "createdAt": "2020-11-09T17:34:28.071123Z",
    "updatedAt": "2020-11-09T17:34:28.144826Z",
    "sourceDataset": "source",
    "targetDataset": "target",
		"withHistory" true/false
},
 // ...
]

List active features

GET /v2021-06-07/projects/:id/features

Returns a list of all active features on your project.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/features' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

[
  "privateDataset"
]

Check if a feature is active

GET /v2021-06-07/projects/:id/features/:name

Shows whether a specific feature is enabled on your project. Current features you can check for are privateDataset and thirdPartyLogin.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/features/thirdPartyLogin' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

false

List project permissions

GET /v2021-06-07/projects/:id/permissions

Returns a list of permissions you have as a member of a project.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/permissions' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

[
  "manageProject",
  "manageUsers",
  "manageCors",
  "manageWebhooks",
  "manageTokens",
  "deployStudio",
  "manageDatasets",
  "readAll",
  "writeAll"
]

Retrieve a user

GET /v2021-06-07/projects/:projectId/users/:id

Fetches the details of a user on a project.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/users/h87f1dh9' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

{
  "id": "h87f1dh9",
  "sanityUserId": "9Ha09aoi",
  "projectId": "54n1ty10",
  "displayName": "Arthur Dent",
  "familyName": "Dent",
  "givenName": "Arthur",
  "middleName": null,
  "imageUrl": null,
  "createdAt": "2020-04-01T11:31:31.767Z",
  "updatedAt": "2020-04-01T11:31:31.767Z"
}

Protip

Need the currently logged-in user information?

If you don't have a user :id, you can specify me on the /users endpoint to get the details of the current user (obtained via the auth token used):

curl -sH "Authorization: Bearer <auth token>" https://api.sanity.io/v2021-06-07/users/me

You can also access this information in the Sanity JS Client with client.users.getById('me').

List project roles

GET /v2021-06-07/projects/:id/roles

Returns a list of existing roles on a project.

Example

Request

curl GET 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/roles' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json'

Response

[
  {
    "id": "administrator",
    "name": "Administrator",
    "description": "Manage all aspects of the project",
    "isRootRole": true,
    "readOnly": true,
    "isListed": true,
    "permissions": [
      "manageProject",
      "manageUsers",
      "manageCors",
      "manageWebhooks",
      "manageTokens",
      "deployStudio",
      "manageDatasets",
      "readAll",
      "writeAll"
    ]
  },
  {
    "id": "write",
    "name": "Read+Write",
    "description": "Read and write from/to all datasets within the project",
    "isRootRole": true,
    "readOnly": true,
    "isListed": true,
    "permissions": [
      "writeAll",
      "readAll"
    ]
  },
  {
    "id": "read",
    "name": "Read",
    "description": "Read data from all datasets within the project",
    "isRootRole": true,
    "readOnly": true,
    "isListed": true,
    "permissions": [
      "readAll"
    ]
  }
]

List project tokens

GET /v2021-06-07/projects/:projectId/tokens

Returns a list of existing tokens on the project :projectId.

Gotcha

The endpoint does not expose the actual tokens—only information about the tokens.

Example

Request

curl --request GET \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tokens' \
  -H 'Authorization: Bearer <token>'

Response

[
  {
    "id": "si3TnJKagwzJUq",
    "label": "Deploy",
    "projectUserId": "p-rbzaWnePhknL",
    "createdAt": "2022-05-05T16:16:03.775Z",
    "roles": [
      {
        "name": "deploy-studio",
        "title": "Deploy Studio (Token only)"
      }
    ]
  },
  {
    "id": "sijcPBcuvYkThq",
    "label": "Mutate documents",
    "projectUserId": "p-U3XdWnKbPLuL",
    "createdAt": "2022-05-05T16:16:09.765Z",
    "roles": [
      {
        "name": "editor",
        "title": "Editor"
      }
    ]
  },
  {
    "id": "siOZz1dyTC4n2q",
    "label": "Preview client",
    "projectUserId": "p-U3XdWnKbPLuT",
    "createdAt": "2022-05-05T16:16:14.002Z",
    "roles": [
      {
        "name": "viewer",
        "title": "Viewer"
      }
    ]
  }
]

Create a project token

POST /v2021-06-07/projects/:projectId/tokens

Creates a token on the project :projectId.

Parameters

  • REQUIREDlabelstring

    A descriptive label for your token. This can help you identify it later so you know where it's being used.

  • REQUIREDroleNamestring

    The permissions to assign your token. These will vary by plan. On a Free plan, roleName must be viewer, editor, or deploy-studio.

Example

Request

curl --request POST \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tokens' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "label": "Preview client",
    "roleName": "viewer"
  }'

Response

{
	"id": "sibdRigr3bNr4j",
	"key": "skPPnQ0RAR2OLjw1SfI...00N8llxJngK4bHGS4A1nrkdN8nQJ",
	"roles": [
	  {
	    "name": "viewer",
	    "title": "Viewer"
	  }
	],
	"label": "Preview client",
	"projectUserId": "p-Aw84SKzUeYwh"
}

key is your token and cannot be retrieved again later.

Delete a project token

DELETE /v2021-06-07/projects/:projectId/tokens/:tokenId

Deletes the token :tokenId from the project :projectId.

Example

Request

curl --request DELETE \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tokens/sibDrigr3BNr2j' \
  -H 'Authorization: Bearer <token>'

Response

{
	"id": "sibDrigr3BNr2j",
	"deleted": true
}

Gotcha

Use this endpoint with caution. Deleting your token is an irreversible action and it will not be possible to recreate an identical token. There will be no confirmation prompt.

List dataset tags

GET /v2021-06-07/projects/:projectId/datasets/:dataset/tags

List all tags assigned to the dataset :dataset.

Example

Request

curl --request GET \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets/production/tags' \
  -H 'Authorization: Bearer <token>'

Response

[
  {
    "name": "red-tag",
    "title": "Red Tag"
  }
]

Create a dataset tag

POST /v2021-06-07/projects/:projectId/tags

Creates a dataset tag.

Parameters

  • REQUIREDnamestring

    The unique identifier of your tag. May contain lowercase letters (a-z), numbers (0-9), and dashes (-). Must be between 2–20 characters.

  • titlestring

    A descriptive title for your tag.

  • descriptionstring

    A description for your tag.

  • metadataobject

    A set of additional configuration options, including:

    • tone - The color of your tag. Permitted values are default (white), primary (blue), positive (green), caution (yellow), critical (red), and transparent (grey).

Example

Request

curl --request POST \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tags' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "name": "red-tag",
    "title": "Red Tag",
    "description": "It'\''s an incredibly unique tag description.",
    "metadata": {
      "tone": "critical"
    }
  }'

Response

{
	"name": "red-tag",
	"title": "Red Tag",
	"description": "It's an incredibly unique tag description.",
	"metadata": {
		"tone": "critical"
	},
	"datasets": []
}

Datasets cannot be assigned in the POST request. For that, see Assign a dataset tag below.

Edit a dataset tag

PUT /v2021-06-07/projects/:projectId/tags/:tagIdentifier

Edit the name/identifier, title, description, or color of the dataset tag :tagIdentifier.

Parameters

  • namestring

    The unique identifier of your tag. May contain lowercase letters (a-z), numbers (0-9), and dashes (-). Must be between 2–20 characters.

  • titlestring

    A descriptive title for your tag.

  • descriptionstring

    A description for your tag.

  • metadataobject

    A set of additional configuration options, including:

    • tone - The color of your tag. Permitted values are default (white), primary (blue), positive (green), caution (yellow), critical (red), and transparent (grey).

Example

Request

curl --request PUT \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tags/red-tag' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "name": "blue-tag",
    "title": "Blue Tag",
    "description": "The red tag is now blue.",
    "metadata": {
      "tone": "primary"
    }
  }'

Response

{
	"name": "blue-tag",
	"title": "Blue Tag",
	"description": "The red tag is now blue.",
	"metadata": {
		"tone": "primary"
	},
	"datasets": []
}

Assign a dataset tag

PUT /v2021-06-07/projects/:projectId/datasets/:dataset/tags/:tagIdentifier

Assigns the tag :tagIdentifier to the dataset :dataset.

Example

Request

curl --request PUT \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets/production/tags/red-tag' \
  -H 'Authorization: Bearer <token>'

Response

Note: A successful tag assignment will return no response.

Unassign a dataset tag

DELETE /v2021-06-07/projects/:projectId/datasets/:dataset/tags/:tagIdentifier

Removes / unassigns the tag :tagIdentifier from the dataset :dataset.

Example

Request

curl --request DELETE \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets/production/tags/red-tag' \
  -H 'Authorization: Bearer <token>'

Response

{
  "deleted": true
}

Delete a dataset tag

DELETE /v2021-06-07/projects/:projectId/tags/:tagIdentifier

Deletes dataset tag :tagIdentifier. To be deleted, the tag must not be applied to any datasets.

Example

Request

curl --request DELETE \
  --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tags/red-tag' \
  -H 'Authorization: Bearer <token>'

Response

{
	"deleted": true
}

Was this article helpful?