Templates
Browse the template catalog and manage and deploy workspace templates.
These endpoints require a signed-in session. Workspace template operations also require access to the workspace.
CATALOG = https://api.cloud.simplifyd.com/v1/templates
BASE = https://api.cloud.simplifyd.com/v1/workspaces/{workspace}/templatesSet CATALOG and BASE to the URLs above. Set SIMPLIFYD_SESSION_TOKEN to your signed-in session JWT and TEMPLATE to the slug returned by the relevant list call. Replace the example project and environment IDs with your own before deploying.
| Method and path | Response |
|---|---|
GET {CATALOG} | 200 OK with an array of catalog templates |
GET {CATALOG}/{template} | 200 OK with a catalog template by its slug |
GET {CATALOG}/from-repo?repo={url} | 200 OK with repo, template and digest for a public GitHub repository |
GET {BASE} | 200 OK with an array of workspace templates |
GET {BASE}/{template} | 200 OK with one template by its slug |
POST {BASE} | 201 Created with the new template |
PUT {BASE}/{template} | 200 OK with the updated template |
DELETE {BASE}/{template} | 200 OK with {"success":true} |
POST {BASE}/{template}/deploy | 201 Created with the created services and any publishable outputs |
POST {BASE}/from-repo/deploy | 201 Created with the created services and any publishable outputs |
List catalog templates
GET {CATALOG}List the templates available to signed-in users.
curl --fail-with-body "$CATALOG" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN"const response = await fetch(`${CATALOG}`, {
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
},
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
[
{
"name": "Web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}
]Read a catalog template
GET {CATALOG}/{template}Read a catalog entry by slug.
curl --fail-with-body "$CATALOG/$TEMPLATE" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN"const response = await fetch(`${CATALOG}/${TEMPLATE}`, {
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
},
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
{
"name": "Web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}Read a repository template
GET {CATALOG}/from-repo?repo={url}Pass a URL-encoded public GitHub repository URL. The repository must contain a simplifyd.json template file. Replace the example URL with a repository containing a template.
curl --fail-with-body "$CATALOG/from-repo?repo=https%3A%2F%2Fgithub.com%2Fexample%2Fweb-stack" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN"const response = await fetch(`${CATALOG}/from-repo?repo=https%3A%2F%2Fgithub.com%2Fexample%2Fweb-stack`, {
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
},
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
{
"repo": {
"owner": "example",
"name": "web-stack"
},
"template": {
"name": "Web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
},
"digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}Use the returned digest when deploying the repository.
List workspace templates
GET {BASE}List the templates saved in the workspace.
curl --fail-with-body "$BASE" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN"const response = await fetch(`${BASE}`, {
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
},
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
[
{
"name": "Web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}
]Read a workspace template
GET {BASE}/{template}Read the definition of one workspace template.
curl --fail-with-body "$BASE/$TEMPLATE" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN"const response = await fetch(`${BASE}/${TEMPLATE}`, {
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
},
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
{
"name": "Web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}Create a template
POST {BASE}
Content-Type: application/jsonSave a template definition in the workspace.
Body
| Field | Description |
|---|---|
name | Required template display name. |
services | Required array with at least one service. Each service needs a unique key. |
services[].docker.image | Required for services of type docker. |
description | Optional description. |
curl --fail-with-body -X POST "$BASE" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"name": "Web server", "services": [{"key": "web", "name": "Web", "type": "docker", "docker": {"image": "nginx", "tag": "alpine"}}]}'const response = await fetch(`${BASE}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({"name": "Web server", "services": [{"key": "web", "name": "Web", "type": "docker", "docker": {"image": "nginx", "tag": "alpine"}}]}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
201 Created.
{
"name": "Web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}Response examples show selected fields.
Update a template
PUT {BASE}/{template}
Content-Type: application/jsonSend the complete updated definition, including the service list.
curl --fail-with-body -X PUT "$BASE/$TEMPLATE" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"name": "Updated web server", "services": [{"key": "web", "name": "Web", "type": "docker", "docker": {"image": "nginx", "tag": "alpine"}}]}'const response = await fetch(`${BASE}/${TEMPLATE}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({"name": "Updated web server", "services": [{"key": "web", "name": "Web", "type": "docker", "docker": {"image": "nginx", "tag": "alpine"}}]}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
{
"name": "Updated web server",
"services": [
{
"key": "web",
"name": "Web",
"type": "docker",
"docker": {
"image": "nginx",
"tag": "alpine"
}
}
],
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"created_at": "2026-01-15T12:00:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}Delete a template
DELETE {BASE}/{template}Remove a template from the workspace.
curl --fail-with-body -X DELETE "$BASE/$TEMPLATE" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN"const response = await fetch(`${BASE}/${TEMPLATE}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
},
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
200 OK.
{
"success": true
}Deploy a saved template
POST {BASE}/{template}/deploy
Content-Type: application/jsonCreate and configure the services described by the template in the target environment. Start their first deployments separately.
Body
| Field | Description |
|---|---|
project | Required project slug. |
env | Required environment slug. |
variables | Optional object keyed by service key and variable name. |
init_sql | Optional initialization SQL for a template configured to accept it. |
curl --fail-with-body -X POST "$BASE/$TEMPLATE/deploy" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"project": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e13", "env": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e14"}'const response = await fetch(`${BASE}/${TEMPLATE}/deploy`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({"project": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e13", "env": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e14"}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
201 Created.
{
"services": [
{
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"name": "Web",
"type": "docker"
}
]
}Deploy a repository template
POST {BASE}/from-repo/deploy
Content-Type: application/jsonCreate services from the repository definition you fetched.
Body
| Field | Description |
|---|---|
repo | Required repository URL used for the lookup. |
digest | Required digest from the lookup response. |
project | Required project slug. |
env | Required environment slug. |
curl --fail-with-body -X POST "$BASE/from-repo/deploy" \
-H "Authorization: Bearer $SIMPLIFYD_SESSION_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"project": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e13", "env": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e14", "repo": "https://github.com/example/web-stack", "digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}'const response = await fetch(`${BASE}/from-repo/deploy`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SIMPLIFYD_SESSION_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({"project": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e13", "env": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e14", "repo": "https://github.com/example/web-stack", "digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.message ?? response.statusText);Response
201 Created.
{
"services": [
{
"slug": "0192e7a0-55c1-7b3e-8f2d-4a1b6c9d0e15",
"name": "Web",
"type": "docker"
}
]
}Replace the example URL and digest with the values for your template. Fetch the definition again if the repository changed.
Errors
| Status | When |
|---|---|
401 | The session is missing or invalid. |
402 | The workspace is suspended when deploying. |
403 | The caller lacks workspace access or used a project token. |
404 | The requested catalog template could not be found. |