Use the GraphQL API to create and manage templates for Pods and Serverless endpoints.
For the complete schema, see the GraphQL Spec.
Quick reference
| Operation | Mutation |
|---|
| Create template | saveTemplate |
| Modify template | saveTemplate (with id) |
| Delete template | deleteTemplate |
| Create secret | secretCreate |
| Delete secret | secretDelete |
Required fields
Templates require the following fields:
| Field | Type | Description |
|---|
containerDiskInGb | Integer | Container disk size in GB. |
imageName | String | Docker image name with tag (e.g., ubuntu:latest). |
name | String | Unique template name. |
volumeInGb | Integer | Volume size in GB. Set to 0 for Serverless templates. |
Template names must be unique. Creating a template with a name that already exists will fail.
Create a template
GPU Pod template
curl --request POST \
--header 'content-type: application/json' \
--url 'https://api.runpod.io/graphql?api_key=${YOUR_API_KEY}' \
--data '{"query": "mutation { saveTemplate(input: { containerDiskInGb: 5, dockerArgs: \"sleep infinity\", env: [ { key: \"key1\", value: \"value1\" }, { key: \"key2\", value: \"value2\" } ], imageName: \"ubuntu:latest\", name: \"My GPU Template\", ports: \"8888/http,22/tcp\", readme: \"## Hello, World!\", volumeInGb: 15, volumeMountPath: \"/workspace\" }) { containerDiskInGb dockerArgs env { key value } id imageName name ports readme volumeInGb volumeMountPath } }"}'
mutation {
saveTemplate(input: {
containerDiskInGb: 5,
dockerArgs: "sleep infinity",
env: [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" }
],
imageName: "ubuntu:latest",
name: "My GPU Template",
ports: "8888/http,22/tcp",
readme: "## Hello, World!",
volumeInGb: 15,
volumeMountPath: "/workspace"
}) {
id
name
imageName
containerDiskInGb
volumeInGb
dockerArgs
ports
env { key value }
}
}
{
"data": {
"saveTemplate": {
"id": "wphkv67a0p",
"name": "My GPU Template",
"imageName": "ubuntu:latest",
"containerDiskInGb": 5,
"volumeInGb": 15,
"dockerArgs": "sleep infinity",
"ports": "8888/http,22/tcp",
"env": [
{ "key": "key1", "value": "value1" },
{ "key": "key2", "value": "value2" }
]
}
}
}
Serverless template
For Serverless templates, set volumeInGb to 0 and include isServerless: true.
curl --request POST \
--header 'content-type: application/json' \
--url 'https://api.runpod.io/graphql?api_key=${YOUR_API_KEY}' \
--data '{"query": "mutation { saveTemplate(input: { containerDiskInGb: 5, dockerArgs: \"python handler.py\", env: [ { key: \"key1\", value: \"value1\" } ], imageName: \"runpod/serverless-hello-world:latest\", isServerless: true, name: \"My Serverless Template\", volumeInGb: 0 }) { id name imageName isServerless containerDiskInGb } }"}'
mutation {
saveTemplate(input: {
containerDiskInGb: 5,
dockerArgs: "python handler.py",
env: [
{ key: "key1", value: "value1" }
],
imageName: "runpod/serverless-hello-world:latest",
isServerless: true,
name: "My Serverless Template",
volumeInGb: 0
}) {
id
name
imageName
isServerless
containerDiskInGb
dockerArgs
env { key value }
}
}
{
"data": {
"saveTemplate": {
"id": "xkhgg72fuo",
"name": "My Serverless Template",
"imageName": "runpod/serverless-hello-world:latest",
"isServerless": true,
"containerDiskInGb": 5,
"dockerArgs": "python handler.py",
"env": [
{ "key": "key1", "value": "value1" }
]
}
}
}
Private container images
For private container images, use containerRegistryAuthId with the ID of your saved registry credentials from your Runpod settings.
mutation {
saveTemplate(input: {
containerDiskInGb: 5,
imageName: "myregistry.io/private-image:latest",
containerRegistryAuthId: "YOUR_REGISTRY_CREDENTIALS_ID",
name: "Private Image Template",
volumeInGb: 10
}) {
id
name
}
}
Modify a template
Include the template id to update an existing template. The same mutation works for both GPU and Serverless templates.
curl --request POST \
--header 'content-type: application/json' \
--url 'https://api.runpod.io/graphql?api_key=${YOUR_API_KEY}' \
--data '{"query": "mutation { saveTemplate(input: { id: \"wphkv67a0p\", containerDiskInGb: 10, imageName: \"ubuntu:latest\", name: \"My GPU Template\", volumeInGb: 20, readme: \"## Updated readme\" }) { id containerDiskInGb volumeInGb readme } }"}'
mutation {
saveTemplate(input: {
id: "wphkv67a0p",
containerDiskInGb: 10,
imageName: "ubuntu:latest",
name: "My GPU Template",
volumeInGb: 20,
readme: "## Updated readme"
}) {
id
containerDiskInGb
volumeInGb
readme
}
}
{
"data": {
"saveTemplate": {
"id": "wphkv67a0p",
"containerDiskInGb": 10,
"volumeInGb": 20,
"readme": "## Updated readme"
}
}
}
Delete a template
Delete a template by name. The template must not be in use by any Pods or Serverless endpoints.
It can take up to 2 minutes to delete a template after its most recent use by a Pod or Serverless endpoint.
curl --request POST \
--header 'content-type: application/json' \
--url 'https://api.runpod.io/graphql?api_key=${YOUR_API_KEY}' \
--data '{"query": "mutation { deleteTemplate(templateName: \"My GPU Template\") }"}'
mutation {
deleteTemplate(templateName: "My GPU Template")
}
{
"data": {
"deleteTemplate": null
}
}
Create a secret
Secrets store sensitive values that can be referenced in templates.
curl --request POST \
--header 'content-type: application/json' \
--url 'https://api.runpod.io/graphql?api_key=${YOUR_API_KEY}' \
--data '{"query": "mutation { secretCreate(input: { value: \"my-secret-value\", name: \"my-secret\" }) { id name description } }"}'
mutation {
secretCreate(input: {
value: "my-secret-value",
name: "my-secret"
}) {
id
name
description
}
}
{
"data": {
"secretCreate": {
"id": "abc123",
"name": "my-secret",
"description": null
}
}
}
Delete a secret
Delete a secret by its ID. You can find the secret ID from the secretCreate response or by querying your secrets.
curl --request POST \
--header 'content-type: application/json' \
--url 'https://api.runpod.io/graphql?api_key=${YOUR_API_KEY}' \
--data '{"query": "mutation { secretDelete(id: \"abc123\") }"}'
mutation {
secretDelete(id: "abc123")
}
{
"data": {
"secretDelete": null
}
}