Prompts API
The prompt library is a data plane for your apps: fetch a versioned prompt by name, or compile it with variable values. Prompts are visible to a key when they are global (no team) or owned by the key's team.
See Prompt library for authoring concepts.
#List prompts
GET /v1/prompts
{ "object": "list", "data": [
{ "name": "support-greeting", "description": "…", "tags": ["support"], "latest_version": 3, "labels": ["production"] }
] }
#Filtering
| Query | Filters by | Example |
|---|---|---|
?tag= | Prompt tags — free-form metadata on the prompt itself | ?tag=support |
?label= | Version labels — which revision is which | ?label=production |
Tags and labels are different things, and the distinction is worth holding on to: a tag describes what a prompt is for and lives on the prompt (support, billing, internal); a label marks which revision to use and lives on a version (production, staging). production and latest are labels, not tags — so ?label=latest, not ?tag=latest.
Both accept a comma-separated list, and both mean all of these, not any of these — a filter narrows, so naming two values returns fewer results:
# Prompts tagged BOTH support and billing
curl "http://localhost:5300/v1/prompts?tag=support,billing" -H "Authorization: Bearer $RELAY_API_KEY"
# Prompts that have a production version
curl "http://localhost:5300/v1/prompts?label=production" -H "Authorization: Bearer $RELAY_API_KEY"
# Combine: support prompts that are live
curl "http://localhost:5300/v1/prompts?tag=support&label=production" -H "Authorization: Bearer $RELAY_API_KEY"
Multiple labels must sit on the same version — ?label=production,canary finds prompts with one version carrying both, not prompts that happen to have each label somewhere.
?label=latest means "has at least one version". That mirrors the fetch endpoint, where latest resolves to the highest version number rather than to a stored label — so a prompt listed under ?label=latest is always fetchable with ?label=latest, and one with no versions appears under neither.
Omit both parameters to list everything, as before.
#Fetch a version
GET /v1/prompts/{name} — resolves, in order: ?version=N → ?label=<label> → the production label → the latest version.
A prompt in a folder is fetched by its full name with the / URL-encoded: support/greeting is /v1/prompts/support%2Fgreeting. The same applies to /compile.
curl "http://localhost:5300/v1/prompts/support-greeting?label=production" \
-H "Authorization: Bearer $RELAY_API_KEY"
{
"name": "support-greeting",
"version": 3,
"type": "text",
"labels": ["production"],
"variables": ["company", "customer"],
"prompt": "You are a support agent for {{company}}. Greet {{customer}}.",
"config": { }
}
For a chat-type prompt the payload has messages (an array of { role, content }) instead of prompt.
#Compile with variables
POST /v1/prompts/{name}/compile — fetch a version (same resolution rules via label/version) and substitute {{variables}}.
curl -X POST "http://localhost:5300/v1/prompts/support-greeting/compile" \
-H "Authorization: Bearer $RELAY_API_KEY" -H "Content-Type: application/json" \
-d '{ "variables": { "company": "Spinneys", "customer": "Sara" } }'
{
"name": "support-greeting",
"version": 3,
"type": "text",
"prompt": "You are a support agent for Spinneys. Greet Sara.",
"missing_variables": [],
"config": { }
}
missing_variables lists any placeholder that wasn't supplied — unprovided placeholders are left intact so you can see what's missing.
#Typical flow
- Author and label a prompt
productionin the panel. - Your app fetches (or compiles) it at runtime by name.
- You send the compiled text/messages to
/v1/chat/completions.
Or skip the round trip entirely and attach the prompt to an agent — the agent resolves and compiles it server-side.