Deploy, read, change and delete a composition
Deploy the Featured post Template, then read, change, list and delete compositions through the Studio API. You need this after you create a composition, or when you manage compositions you already have.
The example continues from Create a section and a template with the API: the Featured post Template and the Post body Section exist.
Prerequisites
- A composition to work on. The example uses Featured post,
blt7777777777777777, and Post body,blt6666666666666666, from the last page. - The same credential and headers. The curl commands on this page read an OAuth access token from
CS_ACCESS_TOKEN, and send the organization UID inorganization_uid. See Make your first call. - To deploy from Studio, a preview environment with a URL for your language. See Project settings.
What this is and what you get
Deploy puts a composition on your site. Reading, changing, listing and deleting manage the compositions you already have.
The routes on this page are the read, update, list, references and delete routes. They all sit under /v1/projects/{projectUid}/compositions.
| Method | Path after /compositions | What it does |
|---|---|---|
GET | /{uid} | Returns one composition. |
PUT | /{uid} | Changes a composition. |
GET | none, /templates or /sections | Lists compositions. |
GET | /{uid}/references | Lists what references a composition. |
DELETE | /{uid} | Deletes a composition. It answers 409 if another composition places it, unless you pass force=true. |
For every field and parameter, see Composition routes.
Deploy the template
Deploy is a Contentstack publish of the composition entry to the environments you pick. It's one operation. The Studio API has no deploy or publish route, and a create leaves the entry unpublished.
To deploy Featured post, open it in the canvas and click Deploy. Save, preview, deploy walks through the dialog.
- Send with References publishes Featured post and every Section its layout places, such as Post hero and Post body.
- Send without References publishes only Featured post.
Deploy publishes only composition entries. It never publishes the connected entry, such as Featured, so publish that in Contentstack on its own.
Your site reads compositions through your Delivery SDK stack. It needs the Template, each Section it places and the connected entry published to that stack's environment.
Studio shows "Template Published Successfully". The Publish Status column of the Templates tab shows the environment you picked for Featured post.
Deploy from code
Deploy is a call to Contentstack, not to the Studio API. To deploy without Studio, make the call Studio makes. This one is Send without References. It publishes Featured post to the production environment in en-us.
curl -X POST "https://api.contentstack.io/v3/content_types/compositions/entries/blt7777777777777777/publish" \
-H "api_key: blt1234567890" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "entry": { "environments": ["blt1111111111111111"], "locales": ["en-us"] }, "version": 1, "locale": "en-us" }'
api_keyis the stack's API key. The URL is the AWS NA host. For other regions, see Contentstack's API endpoints.environmentstakes environment UIDs. Studio sends UIDs, not names. Forproductionin the example, that'sblt1111111111111111.versionis the entry's version. Studio reads_versionfrom the entry and sends it.- Studio also sends
publish_all_localized=trueandapprovals=trueas query parameters, andrules.approvalsin the body, so your stack's approval rules apply.
Send with References calls POST /v3/bulk/publish instead. It sets publish_with_reference to true, sends the header api_version: 3.2, and lists the Template in entries.
publish_with_reference covers only direct references. Studio adds the default Section of each Section Slot to entries itself, so a call from code has to do the same.
The Publish Status column in Studio shows a publish made this way too.
Read a composition back
To read a composition, send a GET with its entry UID. Add decompression=true to get ui as a JSON object.
curl "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567/compositions/blt7777777777777777?decompression=true" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"
The answer has composition and meta. With decompression=true, ui is a JSON object and data_sources is an array. meta.compressed says which form you got.
Without decompression=true, ui comes back as stored. For an entry the API or Studio wrote, that's a zlib: string, and meta.compressed is true. The prefix zlib: marks a base64 string of a zlib deflate stream of the ui JSON.
- You never send
zlib:. The API takesuionly as an object. - Only the exact text
trueturns ondecompression. A value such as1leavesuicompressed. - The read uses the project's locale. Add
localeto read another one.
Change, list or delete a composition
To change a composition, send a PUT to its entry UID with only the fields that change. The API keeps the rest.
The example puts Post body above Post hero. Read Featured post with decompression=true and swap the two nodes in its slot. Save the result in featured-post-ui.json, inside an object with one key, ui.
curl -i -X PUT "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567/compositions/blt7777777777777777" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222" \
-H "Content-Type: application/json" \
--data @featured-post-ui.json
The call answers 200 with the saved composition. Because you sent ui, the API checks the merged composition, compresses the new tree and works out linked_sections again.
- If you send no
ui,linked_sectionsstays as stored. - You can't change
composable_uid. A different value answers422with error code40. - Changing
urldoesn't updateurl_metadata. Send both. - A
POST,PUTandDELETEalways use the project's locale. Set it to your stack's master language, because Studio opens and saves compositions there. - The API sends no version with an update, so two
PUTcalls to one composition don't conflict. The last one wins. - The API checks the stored layout on every
PUT, so a stored layout that breaks a rule fails aPUTto any field.
To find compositions, send a GET to /compositions, /compositions/templates or /compositions/sections. This call lists the Templates with Featured in the title.
curl "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567/compositions/templates?title=Featured" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"
The answer has compositions and meta. These parameters work on all three routes.
| Parameter | Default | What it does |
|---|---|---|
composable_uid | none | Returns the composition with exactly this ID. |
title | none | Returns compositions whose title contains this text, ignoring case. |
limit | 50 | How many to return, from 1 to 100. A higher number answers 400. |
include_ui | false | true adds ui and data_sources to each item. Without it, each item leaves both out. |
For the rest, see Parameters for listing compositions.
To delete a composition, send a DELETE to its entry UID. This call deletes Featured post. Deleting a Template doesn't delete the Sections it places.
curl -i -X DELETE "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567/compositions/blt7777777777777777" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"
The call answers 200 with "Composition deleted successfully".
If another composition places the one you delete, the call answers 409 with error code 41. Post body is placed by Featured post and by the Blog post template, so deleting it first fails. errors.references lists them. Its message ends with this text.
Pass ?force=true to delete anyway.
To see what places a composition, with the titles, call its /references route. This call lists what uses Post body.
curl "https://composable-studio-api.contentstack.com/v1/projects/0123456789abcdef01234567/compositions/blt6666666666666666/references" \
-H "authorization: Bearer $CS_ACCESS_TOKEN" \
-H "organization_uid: blt2222222222222222"
The answer has references and meta.count. Add force=true to the DELETE to skip the check. Any other value, such as 1, leaves the check on.
If it doesn't work
The table covers a failed API call. API errors and validation lists every status code and layout rule.
| You see | What's wrong | What to do |
|---|---|---|
401 with error code 39 | Neither an authtoken nor an authorization: Bearer token reached the API. | Send one of them on every call. |
404 with error code 1 | No project in this organization has that UID, or you can't read it. | Check the project UID, organization_uid and the host for your region. |
404 with error code 30 | No composition in the project's stack has the UID in the path. | Check the UID in the path. |
422 with error code 21 and "Stack not found" | Your token can't write to the project's connected stack. | Use a token with write access to that stack. |
409 with error code 41 | You deleted a composition that another one uses. | Delete the Template first, or add force=true. |
422 with error code 37 | You asked for decompression=true, but the stored ui can't be read. | Read the composition without decompression=true. |
If Deploy is greyed out, or Studio shows "Failed to deploy the template", see Save, preview, deploy.
On your site, the SDK rejects with COMPOSITION_NOT_FOUND or COMPOSITION_NOT_FOUND_BY_URL when the composition entry isn't published to the stack's environment. Deploy the Template. It rejects with PREVIEW_ENTRY_NOT_FOUND when a Template matched but its connected content type has no matching entry.
Where to go next:
- Look up every route and parameter: API endpoints.
- Build a layout with other nodes: Composition JSON.
- Copy a worked tree for another Section or Template: Section and template JSON examples.