12 KiB
HTTP API Reference
This is the canonical public HTTP contract for Scriptorium.
Service And Route
POST /v1/runs runs one prompt request and returns generated output,
validation, and metadata. The service has no built-in authentication or
authorization; deploy it behind appropriate network and authentication controls.
The service address and HTTP limits are configured as described in the
configuration reference. serve invocation is defined in the
CLI reference.
Requests and responses are JSON objects. Requests are decoded as JSON regardless
of their Content-Type; successful JSON responses use
Content-Type: application/json. There are no query parameters.
Request Limits
The configured request-body limit includes inline artifact bodies. The artifact
limit applies to HTTP file inputs. The response limit applies to the encoded
response, including the artifact body, optional raw output, and optional execution report. A limit of zero
disables that limit.
A request body over its limit returns 413 request_too_large; an oversized
file input returns 413 artifact_too_large; an oversized encoded response
returns 413 response_too_large.
POST /v1/runs
Request Body
The maintained request example is a complete copyable shape. At the HTTP adapter boundary, the smallest valid shape is:
{
"prompt_id": "generic.markdown_summary"
}
| Field | Required | Meaning |
|---|---|---|
prompt_id |
yes | Non-blank prompt ID. |
prompt_version |
no | Prompt version filter. |
profile_id |
no | Execution-profile ID; otherwise the prompt must set default_profile. |
session_id |
no | Optional direct, non-secret session identifier. |
inputs |
no | Optional object mapping input names to references. Promptkit decides whether the selected definition needs them. |
vars |
no | Object mapping template-variable names to strings. |
model |
no | Runtime model-override object. |
include_raw_output |
no | Include raw_model_output when true. |
include_execution_report |
no | Include a terminal execution report when true and Promptkit supplies a terminal observation. Omitted, null, or false leaves reporting off. |
transient_retries |
no | Nonnegative additional transient attempt count for this run. Omitted or null inherits the configured engine value and then Promptkit's default; 0 disables additional attempts. |
run_timeout_seconds |
no | Optional signed 64-bit whole-second limit for engine execution. Omitted, null, or 0 adds no deadline; positive values shorten the caller context deadline. |
An input reference has a required type of file or inline. A file
reference requires uri; an inline reference requires body.
HTTP file references require a configured artifact root. Relative paths resolve
within that root. Absolute paths must be lexically within it; traversal outside
it is rejected with 400 artifact_not_allowed. This lexical check does not
resolve symlinks: the operating system follows symlinks inside the root,
including ones that target outside it. Keep the root narrow and inaccessible to
untrusted writers.
The optional model object accepts endpoint, model, temperature,
max_tokens, top_p, timeout_seconds, service_tier,
reasoning_effort, api_key_env, and extra_params. Numeric ranges and
framework credential semantics are defined by the
Promptkit format reference.
Explicit zero values for the numeric fields are overrides; zero
timeout_seconds disables the per-attempt generation deadline only, retaining the
request context and configured transport cap. The timeout layers are defined in
the Promptkit outbound integration contract.
Each built-in transient retry gets a fresh generation timeout; the caller's
request context remains the outer cancellation boundary.
Raw API-key values are not accepted. api_key and any other unknown model
field cause 400 invalid_json.
model.reasoning_effort is an optional JSON string with three states: omission
inherits the selected profile, a non-empty string replaces its value, and an
empty string explicitly clears it. JSON null is treated as omission.
session_id is passed directly to Promptkit. A nonblank value replaces a
definition-rendered session ID; omission or a blank value lets the definition
provide one. Promptkit trims direct values and limits them to 256 Unicode code
points. Session IDs are not credentials and may be included in prepared data,
results, and provider-facing requests, so use stable non-sensitive identifiers.
Strict JSON
Request decoding rejects malformed JSON, unknown fields at every request level,
and trailing JSON tokens with 400 invalid_json. A blank prompt_id returns
400 invalid_request. Omitted or empty inputs are passed to Promptkit, which
reports any definition-required or template-referenced inputs.
transient_retries must be a JSON integer; a wrong type or noninteger number
returns 400 invalid_json, while a negative integer returns
400 invalid_request before execution. A request override does not change the
shared engine setting used by other requests. Promptkit owns eligible statuses,
retry waits, and the separate transient budget for each repair generation.
run_timeout_seconds must be a JSON int64. A wrong type or int64 overflow
returns 400 invalid_json; a negative value or one whose conversion to a Go
duration would overflow returns 400 invalid_request. The deadline starts
immediately before engine execution and excludes body decoding and response
writing. An earlier caller deadline or cancellation still wins. Synchronous
work is not guaranteed to stop immediately.
Success Response
A completed run returns 200 OK, including when generated content fails its
validation contract. The response contains:
artifact:name,content_type,body,size,hash, and optionaluri;validation:status,mode,repair_attempts,is_valid, plus optionalerrorsandschema_path;metadata: run, prompt, rendered-prompt, profile, optional backend identity, model, input-hash, usage, timing, validation, and repair-attempt metadata; and- optional
raw_model_outputwhen requested. - optional
executionwhen requested and a terminal observation exists.
metadata.model_params has endpoint, model, temperature,
max_tokens, top_p, and timeout_seconds, plus optional
backend_id, service_tier, reasoning_effort, api_key_env, and extra_params.
metadata.usage always includes prompt_tokens, completion_tokens,
total_tokens, cached_tokens, and cache_write_tokens; unavailable
cache usage is reported as zero.
When Promptkit resolves a direct or definition-rendered session ID,
metadata.session_id contains that effective result value. It is omitted when
no effective session ID exists.
metadata.selected_backend_id and metadata.model_params.backend_id report
the corresponding Promptkit result fields independently when present. Both are
omitted for an endpoint-only profile; Scriptorium does not infer backend
identity from an endpoint.
A validation failure has validation.status: "failed", is_valid: false,
and any available diagnostic errors, while still returning the artifact and
metadata.
Execution Report
The opt-in execution object projects one Promptkit terminal observation. It
is independent of metadata.usage, which retains its existing result-based
meaning. A terminal event can describe a failed invocation even when no provider
call was dispatched; if there is no terminal event, execution is omitted.
| Field | Meaning |
|---|---|
run_id, prompt_id, prompt_version, profile_id, backend_id, model |
Terminal identifiers; absent values are omitted. |
outcome |
success, invalid_output, error, or other for an unrecognized upstream value. |
failure |
The known terminal failure category, none, or other for an unrecognized value. |
status_code |
Provider status, omitted when unavailable. |
retries_exhausted |
Boolean independent of the failure category. |
attempts, transient_retries, repair_calls |
Unsigned terminal aggregate counts. |
duration_ms, capacity_wait_ms, generation_duration_ms, retry_delay_ms |
Terminal observed durations in integer milliseconds; their sum need not equal wall time. |
usage |
Object containing prompt_tokens, completion_tokens, total_tokens, cached_tokens, and cache_write_tokens. |
Each usage count contains value (integer), known (boolean), and
complete (boolean). Reported zero differs from an unknown count; an
incomplete total does not establish complete billing. All counts, durations,
retries_exhausted, and usage are present even when zero or unknown. The
recognized failure values are none, canceled, deadline, transport,
provider_status, malformed_response, capacity, invalid_config,
invalid_request, prompt_not_found, profile_not_found, prompt_load,
profile_load, artifact_load, prompt_render, validation, generation,
and other.
The report excludes content, credentials, URLs, headers, and raw errors, but its identifiers can still be sensitive. Apply appropriate access and retention controls to responses that include it.
Error Responses
Errors have this shape:
{"error":{"code":"invalid_request","message":"prompt_id is required"}}
Messages are concise and do not expose wrapped internal causes.
For an opted-in failed invocation, the error envelope can also include the
optional top-level execution object described above. Decode and validation
failures before engine invocation do not have a report. Report-bearing error
responses are subject to the complete encoded response-size limit; if they
exceed it, the response is the compact 413 response_too_large error without
execution. The existing compact error fallback itself is not re-limited.
| Status | Code | Meaning |
|---|---|---|
400 |
invalid_json |
Malformed JSON, unknown field, or trailing JSON. |
400 |
invalid_request |
Missing or invalid request data or runtime override. |
400 |
profile_required |
No profile ID and no prompt default profile. |
400 |
prompt_load_failed |
Prompt definition failed to load. |
400 |
profile_load_failed |
Profile failed to load. |
400 |
artifact_not_allowed |
HTTP file input is disabled or outside the artifact root. |
400 |
artifact_read_failed |
Input artifact is invalid or cannot be read. |
400 |
prompt_render_failed |
Prompt template rendering failed. |
400 |
api_key_env_missing |
The selected credential environment variable is unset or empty. |
404 |
not_found |
Route does not exist. |
404 |
prompt_not_found |
Prompt ID or version does not exist. |
404 |
profile_not_found |
Profile ID does not exist. |
405 |
method_not_allowed |
The route does not accept the method. |
408 |
request_canceled |
The caller context was canceled during a failed run. |
413 |
request_too_large |
Encoded request exceeds its limit. |
413 |
artifact_too_large |
File input exceeds its limit. |
413 |
response_too_large |
Encoded response exceeds its limit. |
500 |
validation_runtime_failed |
Schema or validator runtime failure. |
500 |
internal_error |
Unclassified server failure. |
502 |
llm_failed |
Outbound model request failed. |
503 |
capacity_exceeded |
The selected model backend has no admission capacity. No retry timing is supplied. |
504 |
deadline_exceeded |
The execution context's deadline expired during a failed run. |
These context outcomes require the execution context to have ended. A provider
attempt timeout while it remains live retains 502 llm_failed. A successful
run remains successful even if cancellation races with response formatting;
delivery after a client disconnect cannot be guaranteed.
Retry And Idempotency
Scriptorium provides no idempotency keys, pagination, caching headers, or rate
limits. Clients may retry transport failures or 5xx responses only when
their workflow tolerates another model call: a retry can produce different
output and incur another provider request.