2026-07-05 02:56:57 +00:00
# HTTP API Reference
2026-05-26 03:31:01 +00:00
## Scope
2026-07-05 02:56:57 +00:00
This document is the canonical public HTTP contract for Scriptorium.
2026-05-26 03:31:01 +00:00
Current scope is only:
- `POST /v1/runs`
2026-07-05 02:56:57 +00:00
For CLI behavior, see the [CLI reference ](cli.md ).
2026-05-26 03:31:01 +00:00
## Endpoint
- Method: `POST`
- Path: `/v1/runs`
- Content type: JSON request/response
Route behavior:
- unknown path: `404 not_found`
- unsupported method on `/v1/runs` : `405 method_not_allowed`
2026-05-26 03:33:25 +00:00
Copyable request example file:
- `examples/http-run.json`
2026-05-26 03:31:01 +00:00
## Request Body
```json
{
"prompt_id": "generic.structured_events",
"profile_id": "local-quality",
"prompt_version": "1.0.0",
"inputs": {
"transcript": {"type": "file", "uri": "./examples/fixtures/transcript.md"},
"glossary": {"type": "inline", "body": "party:\n - Rin"}
},
"vars": {
"session_date": "2026-05-04"
},
"model": {
"endpoint": "http://localhost:8000/v1",
"model": "gpt-4o-mini",
"temperature": 0.0,
"max_tokens": 800,
"top_p": 1.0,
"timeout_seconds": 120,
2026-05-26 07:44:49 -05:00
"service_tier": "priority",
2026-05-26 03:31:01 +00:00
"reasoning_effort": "medium",
"api_key_env": "SCRIPTORIUM_API_KEY",
"extra_params": {
2026-07-04 13:29:38 +00:00
"route": "primary",
"provider_options": {
"retry_budget": 2
}
2026-05-26 03:31:01 +00:00
}
},
"include_raw_output": false
}
```
Required fields:
- `prompt_id`
- `inputs` (must contain at least one named input)
Input reference types currently supported by runtime artifact loading:
- `file`
- `inline`
2026-07-04 23:34:44 +00:00
HTTP `file` references require `server.artifact_root` or `serve --artifact-root` .
2026-07-05 00:22:54 +00:00
Relative file URIs resolve against that root. Absolute file URIs are accepted
only when they are lexically inside the root. Requests that escape the root by
lexical traversal, including `..` traversal and absolute paths outside the root,
return `400 artifact_not_allowed` . Symlinks inside the root are followed by the
operating system, including symlinks that point outside the root. The artifact
root must not be writable by untrusted users. `inline` references do not require
an artifact root.
2026-07-05 00:17:07 +00:00
HTTP file artifacts above the configured artifact limit return
`413 artifact_too_large` . Inline bodies are bounded by the request body limit.
2026-07-04 23:34:44 +00:00
2026-07-04 13:29:38 +00:00
Model override notes:
- Numeric model override fields distinguish omitted values from explicit zero values. For example, omitting `temperature` preserves the selected profile/default value, while `"temperature": 0` explicitly sets the effective temperature to zero.
- `extra_params` accepts JSON-compatible values: strings, numbers, booleans, objects, and arrays.
- `extra_params` are passed through effective model metadata and flattened into top-level provider request fields by the OpenAI-compatible client.
- `extra_params` keys must not be empty and must not collide with reserved outbound fields: `model` , `session_id` , `messages` , `temperature` , `max_tokens` , `top_p` , `service_tier` , `reasoning_effort` , or `response_format` .
- Raw API-key values are not accepted. Use `api_key_env` to name an environment variable.
2026-05-26 03:31:01 +00:00
## Strict JSON Rules
Request decoding uses strict JSON field checks:
- unknown request fields are rejected with `400 invalid_json`
- unknown `model` fields are rejected with `400 invalid_json`
- raw API-key payload fields such as `api_key` are rejected as unknown fields
2026-07-05 00:17:07 +00:00
- request bodies above the configured request limit are rejected with `413 request_too_large`
- trailing JSON tokens after the request object are rejected with `400 invalid_json`
2026-05-26 03:31:01 +00:00
## Success Response
Status: `200 OK`
Response shape:
```json
{
"artifact": {
"name": "output",
"content_type": "application/json",
"body": "{\"summary\":\"...\"}",
"uri": "",
"size": 123,
"hash": "..."
},
"validation": {
"status": "passed",
"mode": "json_schema",
"errors": [],
"schema_path": "structured_events.schema.json",
"repair_attempts": 0,
"is_valid": true
},
"metadata": {
"run_id": "...",
"prompt_id": "generic.structured_events",
"prompt_version": "1.0.0",
"prompt_hash": "...",
"rendered_prompt_hash": "...",
"selected_profile_id": "local-quality",
"model_name": "gpt-4o-mini",
"endpoint": "http://localhost:8000/v1",
"model_params": {
"endpoint": "http://localhost:8000/v1",
"model": "gpt-4o-mini",
"temperature": 0,
"max_tokens": 800,
"top_p": 1,
"timeout_seconds": 120,
2026-05-26 07:44:49 -05:00
"service_tier": "priority",
2026-05-26 03:31:01 +00:00
"reasoning_effort": "medium",
"api_key_env": "SCRIPTORIUM_API_KEY",
"extra_params": {
2026-07-04 13:29:38 +00:00
"route": "primary",
"provider_options": {
"retry_budget": 2
}
2026-05-26 03:31:01 +00:00
}
},
"input_hashes": {
"transcript": "..."
},
"usage": {
"prompt_tokens": 11,
"completion_tokens": 22,
2026-07-02 23:10:24 +00:00
"total_tokens": 33,
"cached_tokens": 0,
"cache_write_tokens": 0
2026-05-26 03:31:01 +00:00
},
"start_time": "2026-05-04T12:00:00Z",
"end_time": "2026-05-04T12:00:01Z",
"duration_ms": 1000,
"validation_mode": "json_schema",
"validation_status": "passed",
"repair_attempts_used": 0
}
}
```
`raw_model_output` is omitted by default.
2026-07-02 23:10:24 +00:00
`metadata.usage.cached_tokens` and `metadata.usage.cache_write_tokens` are always present as numbers. They are `0` when the provider omits compatible cache usage fields or reports no cache activity.
2026-05-26 03:31:01 +00:00
To include it, send:
- `"include_raw_output": true`
## Validation Failure Behavior
Validation content failures do not map to HTTP error status.
Behavior:
- status remains `200 OK`
- `validation.status` is `failed`
- validation errors are returned in `validation.errors`
## Error Responses
Error body shape:
```json
{
"error": {
"code": "invalid_request",
"message": "prompt_id is required"
}
}
```
Current error mapping (non-exhaustive):
- `400 invalid_json` : malformed JSON or unknown JSON fields
- `400 invalid_request` : missing/invalid request fields
- `400 profile_required` : no explicit `profile_id` and prompt has no `default_profile`
- `400 prompt_load_failed` : prompt definition invalid/unloadable
- `400 profile_load_failed` : profile invalid/unloadable
2026-07-04 23:34:44 +00:00
- `400 artifact_not_allowed` : file input artifact is outside the configured artifact root or file refs are not enabled
2026-05-26 03:31:01 +00:00
- `400 artifact_read_failed` : input artifact loading failed
- `400 prompt_render_failed` : template render failed
- `400 api_key_env_missing` : named API-key environment variable is missing
2026-07-05 00:17:07 +00:00
- `413 request_too_large` : request body exceeds the configured request limit
- `413 artifact_too_large` : HTTP file input artifact exceeds the configured artifact limit
- `413 response_too_large` : encoded JSON response exceeds the configured response limit
2026-05-26 03:31:01 +00:00
- `404 prompt_not_found`
- `404 profile_not_found`
- `502 llm_failed` : outbound model request failed
- `500 validation_runtime_failed` : validator runtime/schema-load failure
- `500 internal_error`
## Security And Deployment Note
The HTTP adapter has no built-in authentication or authorization.
Deploy behind trusted controls (for example authenticated gateway/reverse proxy and network boundaries).