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
.
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.
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."
}
]
}
]
}
]
POST /v2021-06-07/projects
Creates a new Sanity project.
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.
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"
}
]
}
]
}
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.
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
}
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.
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
- ahex
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 tofalse
.activityFeedEnabledboolean
Enables the activity feed at sanity.io/manage when set to
true
. Disables the activity feed when set tofalse
.
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 /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.
Request
curl --request DELETE \ --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10' \ -H 'Authorization: Bearer <token>'
Response
{
"deleted": true
}
GET /v2021-06-07/projects/:id/cors
Returns a list of all CORS origins allowed to access the API for this project.
Request
curl --request GET \ --url '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"
}
]
POST /v2021-06-07/projects/:id/cors
Allows a new origin to use your project API through CORS. Read about browser security and CORS.
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
Request
curl --request POST \ --url '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 /v2021-06-07/projects/:id/cors/:id
Deletes an existing CORS origin from your project.
Request
curl --request DELETE \ --url '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
}
GET /v2021-06-07/projects/:id/datasets
Returns a list of all datasets available to a project.
Request
curl --request GET \ --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json'
Response
[
{
"name": "production",
"aclMode": "public"
}
]
PUT /v2021-06-07/projects/:id/datasets/:name
Creates a new dataset for your project.
aclModestring
Request
curl --request PUT \ --url '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"
}
PUT /v2021-06-07/projects/:id/datasets/:id/copy
Enterprise Feature: Copies a dataset inside Sanity's infrastructure
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
, orcustom
.
Gotcha
The copy endpoint is available on Business and Enterprise plans.
Request
curl --request PUT \ --url '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 /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.
Request
curl --request DELETE \ --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/datasets/staging' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json'
Response
{
"deleted": true
}
Public API for returning list of copy jobs
GET /v2022-04-01/projects/:projectId/datasets/copy?offset=:offset&limit=:limit&state=:state
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
},
// ...
]
GET /v2021-06-07/projects/:id/features
Returns a list of all active features on your project.
Request
curl --request GET \ --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/features' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json'
Response
[
"privateDataset"
]
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
.
Request
curl --request GET \ --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/features/thirdPartyLogin' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json'
Response
false
GET /v2021-06-07/projects/:id/permissions
Returns a list of permissions you have as a member of a project.
Request
curl --request GET \ --url '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"
]
GET /v2021-06-07/projects/:projectId/users/:id
Fetches the details of a user on a project.
Request
curl --request GET \ --url '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')
.
GET /v2021-06-07/projects/:id/roles
Returns a list of existing roles on a project. View the Roles API reference for additional details.
Request
curl --request GET \ --url '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"
]
}
]
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.
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"
}
]
}
]
POST /v2021-06-07/projects/:projectId/tokens
Creates a token on the project :projectId
.
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 /v2021-06-07/projects/:projectId/tokens/:tokenId
Deletes the token :tokenId
from the project :projectId
.
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.
GET /v2021-06-07/projects/:projectId/datasets/:dataset/tags
List all tags assigned to the dataset :dataset
.
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"
}
]
POST /v2021-06-07/projects/:projectId/tags
Creates a dataset tag.
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 aredefault
(white),primary
(blue),positive
(green),caution
(yellow),critical
(red), andtransparent
(grey).
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.
PUT /v2021-06-07/projects/:projectId/tags/:tagIdentifier
Edit the name/identifier, title, description, or color of the dataset tag :tagIdentifier
.
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 aredefault
(white),primary
(blue),positive
(green),caution
(yellow),critical
(red), andtransparent
(grey).
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": []
}
PUT /v2021-06-07/projects/:projectId/datasets/:dataset/tags/:tagIdentifier
Assigns the tag :tagIdentifier
to the dataset :dataset
.
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.
DELETE /v2021-06-07/projects/:projectId/datasets/:dataset/tags/:tagIdentifier
Removes / unassigns the tag :tagIdentifier
from the dataset :dataset
.
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 /v2021-06-07/projects/:projectId/tags/:tagIdentifier
Deletes dataset tag :tagIdentifier
. To be deleted, the tag must not be applied to any datasets.
Request
curl --request DELETE \ --url 'https://api.sanity.io/v2021-06-07/projects/54n1ty10/tags/red-tag' \ -H 'Authorization: Bearer <token>'
Response
{
"deleted": true
}