Skip to main content

Manage projects with the API

Use the Studio API to create, read, change and delete a Studio project from a script. You need it when you set up a project without the editor, or when you need a project UID for the composition routes.

The example is the Blog project, in the AWS NA region. You create it, read it, change it and then delete it.

Prerequisites​

  • A stack that already has a compositions content type. The API never creates one. The example uses the compositions content type in the stack with the API key blt1234567890.
  • Write access to that stack. To create a project, you need it for the stack you connect. To change or delete one, you need it for the stack the project is connected to now.
  • Your organization UID. Send it in the organization_uid header on every call. The example's is blt2222222222222222.
  • A credential. Send an authtoken session token or an authorization: Bearer OAuth access token. The curl commands on this page read an OAuth access token from CS_ACCESS_TOKEN. See Headers every call needs.
  • The base URL for your region. The example uses AWS NA, https://composable-studio-api.contentstack.com/v1. Every path starts with /v1, and a path without it answers 404. For the other regions, see Base URL for each region.

What this is and what you get​

A project ties one stack, one compositions content type, an environment, a language and a Canvas URL together. The API keeps projects in its own database. Your stack never holds a project record.

The API has five project routes. They change only the project record and never write to your stack.

MethodPathWhat it does
GET/v1/projectsLists the projects you can see in your organization.
GET/v1/projects/{uid}Returns one project.
POST/v1/projectsCreates a project.
PUT/v1/projects/{uid}Changes a project. A top-level field you leave out keeps its value, and settings is replaced whole.
DELETE/v1/projects/{uid}Deletes a project. Its compositions stay in your stack.

For every field and parameter, see Project routes.

You get a project UID, such as 0123456789abcdef01234567 for Blog. It's a 24 character hexadecimal string, not a blt UID. Composition routes take it in the path and find your stack, content type and default language through it. For what each setting does, see What a project holds.

A project has no branch. Studio works on the main branch of the stack.

Faster ways to do this​

  • The Studio editor. Click New Project on the projects page. The dialog asks for Name, Description and Select Stack, and it creates the compositions content type in your stack first. In Settings, the General tab edits Name and Description. The Configuration tab edits Environment, Language, Canvas URL and Enable Freeform Feature. See Create a project.
  • The skill provision-studio-project. It creates the compositions content type, an environment, a delivery token and a preview token, and it turns on Live Preview. It then creates the project and sets the environment, language and Freeform. Before it creates a project, it lists yours and asks whether to reuse one. It has no step that deletes a project. See provision-studio-project.

The CLI can only set or show the active project, with csdx studio:project:set and csdx studio:project:get. It can't create, change or delete a project. See CLI commands.

Create a project​

To create a project, send POST /v1/projects. The request for the Blog project is below. Save it as create-project-body.json.

{
"name": "Blog",
"connectedStackApiKey": "blt1234567890",
"contentTypeUid": "compositions",
"canvasUrl": "/canvas",
"settings": {
"configuration": {
"environment": "blt1111111111111111",
"locale": "en-us"
}
}
}

name, connectedStackApiKey and contentTypeUid are required. description and canvasUrl are optional. These rows come from the full table of fields under Project routes.

FieldRequired on createWhat it holds
nameYesThe project name. Up to 256 characters.
connectedStackApiKeyYesThe API key of the stack the project uses.
contentTypeUidYesThe content type in that stack that holds compositions.
settingsNo{ "configuration": { "environment": "…", "locale": "…" } }. The locale is the one composition calls use when you don't pass one.

In settings.configuration, environment holds the environment's UID, not its name. For production, that's blt1111111111111111. locale holds the language code, en-us. Set it to your stack's master language. Studio opens and saves every Template and Section in the master language, and the API writes in the project's locale. If you leave locale empty, the API sends no language to Contentstack. See Fetch content in a locale.

The API doesn't check that the content type, the environment or the language exists in your stack. A wrong value saves without an error.

Send the request.

curl -X POST "https://composable-studio-api.contentstack.com/v1/projects" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222" \
-H "Content-Type: application/json" \
-d @create-project-body.json

The API answers 201 with a notice and the saved project. The answer below leaves out createdAt and updatedAt, which the API sets.

{
"notice": "Project created successfully",
"project": {
"name": "Blog",
"description": "",
"canvasUrl": "/canvas",
"connectedStackApiKey": "blt1234567890",
"contentTypeUid": "compositions",
"organizationUid": "blt2222222222222222",
"settings": {
"configuration": {
"environment": "blt1111111111111111",
"locale": "en-us"
}
},
"createdBy": "blt3333333333333333",
"updatedBy": "blt3333333333333333",
"deletedAt": false,
"_id": "0123456789abcdef01234567",
"uid": "0123456789abcdef01234567"
}
}

Keep the uid. Every other project route takes it in the path. _id has the same value, and only the create answer includes it.

You don't send organizationUid, createdBy or uid. The API sets them, and it drops any of them you send without an error.

Project names don't have to be unique. One stack can hold several live projects, each with a different content type.

List and read projects​

To find a project's UID, or to see which projects you can reach, send GET /v1/projects.

curl "https://composable-studio-api.contentstack.com/v1/projects" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"

The API answers 200 with { "projects": [ ... ] }. Blog is one of the items. The answer has no count, no page fields and no default limit. The list holds two groups of projects:

  • Live projects in your organization whose stack you can access.
  • Live projects you created. A project you created stays in your list after you lose access to its stack.

The list never includes deleted projects or projects from another organization. If you can see none, the API answers 200 with { "projects": [] }, not 404.

To read one project, send GET /v1/projects/0123456789abcdef01234567.

curl "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"

The API answers 200 with { "project": { ... } } and no notice. The project has the same fields as the create answer, except _id.

Fetch finds a project only when it's live and in your organization. If you can't read a project, the API answers 404 with error code 1, not 422. So the call doesn't confirm that the project exists.

Change a project​

To change a project, send PUT to its path with the fields you want to change. The route takes the same six fields as create, and every one is optional. A top-level field you leave out keeps its stored value.

settings works differently. The API replaces it whole, and doesn't merge it. Send the full configuration and any isFreeformEnabled every time.

The example turns on Enable Freeform Feature for Blog. Save this body as change-project-body.json. It repeats configuration, because the API replaces settings whole.

{
"settings": {
"isFreeformEnabled": true,
"configuration": {
"environment": "blt1111111111111111",
"locale": "en-us"
}
}
}

The API keeps every key you send in settings, such as isFreeformEnabled, and checks none of them. isFreeformEnabled set to true turns on Enable Freeform Feature in Studio.

curl -X PUT "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222" \
-H "Content-Type: application/json" \
-d @change-project-body.json

The API answers 200 with the notice Project updated successfully and the saved project, without _id. Every change sets updatedAt and updatedBy, even when the body is empty.

If you send only isFreeformEnabled, the saved settings loses configuration, so the project loses its environment and its locale.

A few more rules apply to a change:

  • A PUT can't change uid, organizationUid, createdBy or deletedAt. The API drops them.
  • A canvasUrl set to an empty string clears it.

You can point a project at another stack or content type with connectedStackApiKey and contentTypeUid. The editor has no field for this. The API checks your write access against the stack the project is connected to now, before it applies the change. It doesn't check your access to the new stack, or that the new stack or content type exists.

Warning: After you point a project at a stack you can't write to, you can't change or delete the project again. Each call checks the stack the project is connected to.

Changing connectedStackApiKey or contentTypeUid moves no compositions. They stay as entries in the old stack and content type. The project's composition routes then read and write the new ones.

Delete a project​

To delete a project, send DELETE to its path, without a Content-Type header. A DELETE with Content-Type: application/json and no body answers 400 before the route runs.

curl -X DELETE "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"

The API answers 200 with { "notice": "Project deleted successfully" }.

Delete is a soft delete. The API sets deletedAt to the time of the call and deletedBy to your user UID, blt3333333333333333 in the example. The project then drops out of list, fetch, change and delete. Each answers 404 with error code 1. No route restores a deleted project.

Delete doesn't check, count or remove the project's compositions or its content type. They stay in your stack. The editor's Delete Project works differently. It also deletes the compositions content type from the stack.

After you delete a project, you can create another with the same stack and content type.

If it doesn't work​

  • 422 with error code 21 and Stack not found. Your token lacks write access to the stack you named. On a change or delete, that's the stack the project is connected to now. To change or delete a project you pointed at a stack you can't write to, get write access to that stack.
  • 404 with error code 1 and Project not found. The UID is wrong, the project is deleted, or organization_uid is another organization's. errors is { "uid": ["is not valid."] }. On a fetch, it also means you can't access the project.
  • 422 with error code 2 on a create, or 3 on a change. Another live project already uses that stack and content type. errors is { "contentTypeUid": ["is not unique."] }. Use a different content type, or delete the other project first.
  • 400 with a message list. A field is missing, the wrong type or too long. The list holds the first problem for each field, such as name must be a string. name takes up to 256 characters, description up to 1024 and canvasUrl up to 100.
  • 500 with Internal server error on a create. An empty name or contentTypeUid passes validation and then fails. Send a value for both.
  • 400 on a DELETE. You sent Content-Type: application/json with no body. Send the DELETE without a Content-Type header.
  • 408. The call ran past 60 seconds. The body is { "message": "Request Timeout", "statusCode": 408 }.
  • The project saved, but Studio doesn't use your environment or language. The API doesn't check that they exist. Check that environment holds the environment's UID, not its name.
  • The environment and language are gone after a change. The API replaced settings whole. Send the full configuration with every change.
  • A project is missing from the list. The list holds live projects in your organization whose stack you can access, and the ones you created. Check the organization_uid header and your access to the stack.

Where to go next:

Report a problem with this page