Prompt Versions API
All endpoints verified working via curl. Document updated only after curl
confirmation. Unlike the parent Prompts create/edit/delete
endpoints, everything here accepts a Bearer API key. Write operations (POST)
require owner, admin, or editor role.
POST /api/v1/prompts/:id/versions
Commits a new immutable version of a prompt. Version numbers are sequential
(1, 2, 3 …) per prompt. The first commit auto-creates production and staging
aliases pointing to v1; subsequent commits do not change any alias.
Optional model (issue #12): bind a default gateway model to this version by its
publicName. When set, the Playground pre-selects it and a stored-prompt gateway
call that omits model falls back to it (an explicit request model always
wins). Omitted = unbound. Every version response now carries model
(the bound model's current publicName, or null).
curl -X POST $ACRUXCORE_BASE_URL/prompts/a95ea910-c7fc-43c5-9c68-a8750e02a8f5/versions \
-H "Authorization: Bearer $ACRUXCORE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"system","content":"Hello {{ name }}, welcome to {{ company }}."}]}'
Response (status 201) — first commit: includes aliases:
{
"id": "1f720cc8-c817-45a1-a992-02dd2f90af64",
"promptId": "a95ea910-c7fc-43c5-9c68-a8750e02a8f5",
"versionNumber": 1,
"messages": [{"role":"system","content":"Hello {{ name }}, welcome to {{ company }}."}],
"variables": ["name","company"],
"createdBy": "...",
"createdAt": "2026-06-26T22:39:53.801Z",
"aliases": [
{"alias":"production","versionId":"1f720cc8-c817-45a1-a992-02dd2f90af64"},
{"alias":"staging","versionId":"1f720cc8-c817-45a1-a992-02dd2f90af64"}
]
}
Response (status 201) — subsequent commits: no aliases field:
{
"id": "e3d0901f-24e6-4ada-941e-5b590592d2f8",
"promptId": "a95ea910-c7fc-43c5-9c68-a8750e02a8f5",
"versionNumber": 2,
"messages": [{"role":"system","content":"Hi there {{ name }}, {{ company }} is glad you are here."}],
"variables": ["name","company"],
"createdBy": "...",
"createdAt": "2026-06-26T22:40:32.123Z",
"model": null
}
With a bound default model (issue #12) — model is the model's publicName:
curl -X POST $ACRUXCORE_BASE_URL/prompts/91f7b670-3305-47d0-af89-f46263cfabb7/versions \
-H "Authorization: Bearer $ACRUXCORE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"system","content":"Hello {{ name }}"}],"model":"gpt-4o-mini"}'
{
"id": "ff24e4a5-005c-46c9-8cd1-f5715907da89",
"promptId": "91f7b670-3305-47d0-af89-f46263cfabb7",
"versionNumber": 1,
"messages": [{"role":"system","content":"Hello {{ name }}"}],
"variables": ["name"],
"createdBy": "a1ef91ce-3b55-4a70-b687-3275c1c6313f",
"createdAt": "2026-07-12T12:00:03.873Z",
"model": "gpt-4o-mini",
"aliases": [
{"id":"...","alias":"production","versionId":"ff24e4a5-005c-46c9-8cd1-f5715907da89","versionNumber":1,"updatedAt":"..."},
{"id":"...","alias":"staging","versionId":"ff24e4a5-005c-46c9-8cd1-f5715907da89","versionNumber":1,"updatedAt":"..."}
]
}
400 — model is not a registered gateway model for the team (issue #12):
{"error":{"code":"VALIDATION_ERROR","message":"Model 'nope-model' is not registered for this team."}}
400 — invalid nunjucks template syntax:
{"error":{"code":"TEMPLATE_PARSE_ERROR","message":"..."}}
400 — missing or invalid messages field:
{"error":{"code":"VALIDATION_ERROR","message":"..."}}
403 — viewer role cannot commit versions:
{"error":{"code":"FORBIDDEN","message":"You do not have permission to perform this action."}}
404 — prompt does not exist:
{"error":{"code":"NOT_FOUND","message":"Prompt not found"}}
GET /api/v1/prompts/:id/versions
Lists all versions for a prompt, newest first. The messages field is omitted
from list items (fetch a specific version to get messages).
curl $ACRUXCORE_BASE_URL/prompts/a95ea910-c7fc-43c5-9c68-a8750e02a8f5/versions \
-H "Authorization: Bearer $ACRUXCORE_API_KEY"
With pagination:
curl "$ACRUXCORE_BASE_URL/prompts/a95ea910-c7fc-43c5-9c68-a8750e02a8f5/versions?page=1&limit=20" \
-H "Authorization: Bearer $ACRUXCORE_API_KEY"
Response (status 200):
{
"data": [
{
"id": "e3d0901f-24e6-4ada-941e-5b590592d2f8",
"promptId": "a95ea910-c7fc-43c5-9c68-a8750e02a8f5",
"versionNumber": 2,
"variables": ["name","company"],
"createdBy": "...",
"createdAt": "2026-06-26T22:40:32.123Z"
},
{
"id": "1f720cc8-c817-45a1-a992-02dd2f90af64",
"promptId": "a95ea910-c7fc-43c5-9c68-a8750e02a8f5",
"versionNumber": 1,
"variables": ["name","company"],
"createdBy": "...",
"createdAt": "2026-06-26T22:39:53.801Z"
}
],
"total": 2,
"page": 1,
"limit": 20
}
GET /api/v1/prompts/:id/versions/:version_number
Fetches a specific version including its full messages array.
curl $ACRUXCORE_BASE_URL/prompts/a95ea910-c7fc-43c5-9c68-a8750e02a8f5/versions/1 \
-H "Authorization: Bearer $ACRUXCORE_API_KEY"
Response (status 200):
{
"id": "1f720cc8-c817-45a1-a992-02dd2f90af64",
"promptId": "a95ea910-c7fc-43c5-9c68-a8750e02a8f5",
"versionNumber": 1,
"messages": [{"role":"system","content":"Hello {{ name }}, welcome to {{ company }}."}],
"variables": ["name","company"],
"createdBy": "...",
"createdAt": "2026-06-26T22:39:53.801Z"
}
404 — version number does not exist for this prompt:
{"error":{"code":"NOT_FOUND","message":"Version 99 not found for this prompt"}}