Files
scriptorium/docs/integrations/http-api.md

6.1 KiB

HTTP API Integration

Scope

This document defines the implemented inbound HTTP contract for Scriptorium.

Current scope is only:

  • POST /v1/runs

For CLI behavior, see the CLI reference.

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

Copyable request example file:

  • examples/http-run.json

Request Body

{
  "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,
    "service_tier": "priority",
    "reasoning_effort": "medium",
    "api_key_env": "SCRIPTORIUM_API_KEY",
    "extra_params": {
      "route": "primary",
      "provider_options": {
        "retry_budget": 2
      }
    }
  },
  "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

HTTP file references require server.artifact_root or serve --artifact-root. Relative file URIs resolve inside that root. Absolute file URIs are accepted only when they remain inside the root. Requests that escape the root, including .. traversal and absolute paths outside the root, return 400 artifact_not_allowed. inline references do not require an artifact root.

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.

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

Success Response

Status: 200 OK

Response shape:

{
  "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,
      "service_tier": "priority",
      "reasoning_effort": "medium",
      "api_key_env": "SCRIPTORIUM_API_KEY",
      "extra_params": {
        "route": "primary",
        "provider_options": {
          "retry_budget": 2
        }
      }
    },
    "input_hashes": {
      "transcript": "..."
    },
    "usage": {
      "prompt_tokens": 11,
      "completion_tokens": 22,
      "total_tokens": 33,
      "cached_tokens": 0,
      "cache_write_tokens": 0
    },
    "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.

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.

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:

{
  "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
  • 400 artifact_not_allowed: file input artifact is outside the configured artifact root or file refs are not enabled
  • 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
  • 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).