{"openapi":"3.1.0","info":{"title":"Retrace API","version":"1.0.0","summary":"Record, inspect, replay, and evaluate AI agent executions.","description":"The public Retrace API for trace ingestion, semantic search, fork replay, evaluation gates, runtime enforcement, and OpenTelemetry ingestion. API-key and bearer-token authentication are alternative schemes.\n\n## Versioning & Deprecation Policy\n\nThe API uses URL path versioning (e.g. `/api/v1`). Breaking changes are introduced in a new version path; the prior version continues to work for the documented sunset window. Deprecated operations carry RFC 8594 `Deprecation` and `Sunset` response headers indicating when the operation was deprecated and when it will be removed, plus a `Link` header with `rel=\"deprecation\"` pointing at the migration guide. The minimum sunset window is 6 months from the deprecation date. Clients should monitor the Deprecation header and migrate before the Sunset date.","termsOfService":"https://retraceai.tech/terms","contact":{"name":"Retrace support","url":"https://retraceai.tech/contact","email":"hello@retraceai.tech"},"license":{"name":"Retrace API Terms","url":"https://retraceai.tech/terms"}},"externalDocs":{"description":"Retrace API Reference — full guides, SDKs, and examples.","url":"https://docs.retraceai.tech/api-reference"},"jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","servers":[{"url":"https://api.retraceai.tech","description":"Production API"}],"security":[{"RetraceApiKey":[]},{"BearerAuth":[]}],"tags":[{"name":"System","description":"Service health and build identity."},{"name":"Traces","description":"Recorded AI agent executions and their spans."},{"name":"Forks","description":"Branch and replay recorded executions."},{"name":"Search","description":"Semantic search over recorded spans."},{"name":"Evaluations","description":"Behavioral evaluations and CI gates."},{"name":"Enforcement","description":"Pre-call runtime policy decisions."},{"name":"Jobs","description":"Asynchronous job status polling for long-running operations."},{"name":"Batch","description":"Execute multiple API operations in a single request."},{"name":"OpenTelemetry","description":"OTLP/HTTP trace ingestion."}],"paths":{"/health":{"get":{"operationId":"getHealth","summary":"Check API health","description":"Returns the running service version, build identity, timestamp, and uptime without authentication.","tags":["System"],"security":[],"responses":{"200":{"description":"The API is healthy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/api/v1/traces":{"get":{"operationId":"listTraces","summary":"List traces","description":"Lists traces visible to the authenticated account, newest first, with bounded offset pagination.","tags":["Traces"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of records to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"description":"Zero-based pagination offset. Legacy — prefer cursor-based pagination instead.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor returned as next_cursor from a previous response. Cursor-based pagination is preferred over offset for consistency across concurrent writes.","schema":{"type":"string"}},{"name":"env","in":"query","required":false,"description":"Set to sandbox to list only sandbox traces; omit to list production traces.","schema":{"type":"string","enum":["sandbox"]}}],"responses":{"200":{"description":"A paginated trace list.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraceList"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createTrace","summary":"Create or ingest a trace","description":"Creates one trace and optionally ingests up to 1,000 child spans in the same request. Terminal traces trigger downstream detection and evaluation processing.","tags":["Traces"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"The trace and optional span batch to record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTraceRequest"}}}},"responses":{"200":{"description":"The trace was created, or a previously persisted terminal fork trace was resumed safely.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraceCreateResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A trace with this identifier already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/traces/{traceId}":{"parameters":[{"name":"traceId","in":"path","required":true,"description":"Trace UUID.","schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getTrace","summary":"Get a trace","description":"Returns one visible trace with its ordered spans and optional causal ordering metadata.","tags":["Traces"],"responses":{"200":{"description":"The requested trace and child spans.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraceDetail"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The trace does not exist or is not visible to the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"finishTrace","summary":"Update trace terminal state","description":"Completes the HTTP fallback lifecycle for an existing trace by recording its status, output, totals, and end time.","tags":["Traces"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Terminal trace fields to update.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishTraceRequest"}}}},"responses":{"200":{"description":"The trace was updated.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraceCreateResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The trace does not exist or is not owned by the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteTrace","summary":"Delete a trace","description":"Soft-deletes a trace owned by the authenticated account; associated data is removed by the retention cleanup process.","tags":["Traces"],"responses":{"200":{"description":"The trace was marked deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The trace does not exist or is not owned by the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/forks":{"get":{"operationId":"listForks","summary":"List forks","description":"Lists fork records owned by the authenticated account, newest first.","tags":["Forks"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of records to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"description":"Zero-based pagination offset. Legacy — prefer cursor-based pagination instead.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor returned as next_cursor from a previous response. Cursor-based pagination is preferred over offset for consistency across concurrent writes.","schema":{"type":"string"}}],"responses":{"200":{"description":"A paginated fork list.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForkList"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createFork","summary":"Create a fork","description":"Creates a branch from an owned trace at a specific span with a replacement input and optional mocked tool outputs.","tags":["Forks"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Fork point and modified input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateForkRequest"}}}},"responses":{"200":{"description":"The fork was created in pending state.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Fork"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The source trace does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/forks/{forkId}":{"parameters":[{"name":"forkId","in":"path","required":true,"description":"Fork UUID.","schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getFork","summary":"Get a fork","description":"Returns one fork owned by the authenticated account.","tags":["Forks"],"responses":{"200":{"description":"The requested fork.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Fork"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The fork does not exist or is not owned by the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/forks/{forkId}/replay":{"parameters":[{"name":"forkId","in":"path","required":true,"description":"Fork UUID to replay.","schema":{"type":"string","format":"uuid"}}],"post":{"operationId":"replayFork","summary":"Replay a fork","description":"Reserves replay quota and re-executes the fork through a connected resumable SDK or the server fallback. This operation can incur model cost.","tags":["Forks"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"description":"No body is required.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"200":{"description":"Replay started or completed.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayResult"}}}},"202":{"description":"Replay accepted and running asynchronously. Poll the job status resource for progress.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"Location":{"description":"URL of the job status resource to poll for completion.","schema":{"type":"string","format":"uri"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Monthly fork-replay allowance is exhausted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Another replay generation is already active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/search":{"post":{"operationId":"searchSpans","summary":"Search recorded spans","description":"Runs semantic similarity search over spans owned by the caller and applies optional typed filters.","tags":["Search"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Natural-language query, filters, and pagination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Ranked semantic search results.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evaluations":{"get":{"operationId":"listEvaluations","summary":"List evaluations","description":"Lists evaluations the authenticated account may run.","tags":["Evaluations"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of records to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"description":"Zero-based pagination offset. Legacy — prefer cursor-based pagination instead.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor returned as next_cursor from a previous response. Cursor-based pagination is preferred over offset for consistency across concurrent writes.","schema":{"type":"string"}}],"responses":{"200":{"description":"A paginated evaluation list.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationList"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createEvaluation","summary":"Create an evaluation","description":"Creates a weighted behavioral evaluation that can score one or more recorded traces.","tags":["Evaluations"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Evaluation name, judge model, and weighted criteria.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvaluationRequest"}}}},"responses":{"200":{"description":"The evaluation was created.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evaluation"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evaluations/{evaluationId}":{"parameters":[{"name":"evaluationId","in":"path","required":true,"description":"Evaluation UUID.","schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getEvaluation","summary":"Get an evaluation","description":"Returns one visible evaluation and a bounded history of its runs.","tags":["Evaluations"],"responses":{"200":{"description":"The evaluation and recent runs.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationDetail"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The evaluation does not exist or is not visible.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteEvaluation","summary":"Delete an evaluation","description":"Soft-deletes an evaluation visible to and manageable by the caller.","tags":["Evaluations"],"responses":{"200":{"description":"The evaluation was marked deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The evaluation does not exist or is not visible.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evaluations/{evaluationId}/run":{"parameters":[{"name":"evaluationId","in":"path","required":true,"description":"Evaluation UUID to run.","schema":{"type":"string","format":"uuid"}}],"post":{"operationId":"runEvaluation","summary":"Run an evaluation","description":"Queues an evaluation run for each owned trace UUID in the request.","tags":["Evaluations"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Trace UUIDs to score and an optional judge-model override.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunEvaluationRequest"}}}},"responses":{"200":{"description":"Evaluation runs were queued.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunEvaluationResult"}}}},"202":{"description":"Evaluation accepted and running asynchronously. Poll the job status resource for progress.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"},"Location":{"description":"URL of the job status resource to poll for completion.","schema":{"type":"string","format":"uri"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The evaluation does not exist or is not visible.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evaluations/{evaluationId}/gate":{"parameters":[{"name":"evaluationId","in":"path","required":true,"description":"Evaluation UUID used as the CI gate.","schema":{"type":"string","format":"uuid"}}],"post":{"operationId":"runEvaluationGate","summary":"Run a CI evaluation gate","description":"Scores the supplied traces against a threshold and returns a typed pass/fail result suitable for deployment automation.","tags":["Evaluations"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Trace set, pass threshold, and regression policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationGateRequest"}}}},"responses":{"200":{"description":"The gate completed with a pass/fail verdict.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationGateResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The evaluation does not exist or is not visible.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/enforcement/check":{"post":{"operationId":"checkEnforcement","summary":"Check an action before execution","description":"Evaluates runtime circuit-breaker policies before a model or tool action runs and fails closed when policy state cannot be loaded.","tags":["Enforcement"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Proposed action metadata. Tool arguments should be hashed client-side.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnforcementCheckRequest"}}}},"responses":{"200":{"description":"An allow, block, or hold decision.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnforcementDecision"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{jobId}":{"parameters":[{"name":"jobId","in":"path","required":true,"description":"Job UUID returned in the Location header of a 202 response.","schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getJob","summary":"Get job status","description":"Returns the current status of a long-running asynchronous job such as a fork replay or evaluation run. Poll this endpoint until status is 'succeeded' or 'failed'.","tags":["Jobs"],"responses":{"200":{"description":"The current job status.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The job does not exist or is not visible to the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/batch":{"post":{"operationId":"executeBatch","summary":"Execute a batch of operations","description":"Accepts up to 50 sub-requests in a single HTTP call and returns their individual responses. Each operation is executed independently; a failure in one does not roll back others. Operation ids must be unique within the batch.","tags":["Batch"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"description":"Batch of sub-requests to execute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"}}}},"responses":{"200":{"description":"All sub-requests have been processed. Individual results may contain error statuses.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/traces":{"post":{"operationId":"ingestOtlpTraces","summary":"Ingest OpenTelemetry traces","description":"Accepts OTLP/HTTP JSON or protobuf, maps GenAI semantic attributes into Retrace spans, and creates at most 2,000 spans per request.","tags":["OpenTelemetry"],"security":[{"RetraceApiKey":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"name":"Content-Type","in":"header","required":true,"description":"OTLP encoding used by the request.","schema":{"type":"string","enum":["application/json","application/x-protobuf","application/protobuf"]}}],"requestBody":{"required":true,"description":"OTLP ExportTraceServiceRequest encoded as JSON or protobuf.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtlpTraceRequest"}},"application/x-protobuf":{"schema":{"type":"string","contentMediaType":"application/x-protobuf","contentEncoding":"base64"}},"application/protobuf":{"schema":{"type":"string","contentMediaType":"application/protobuf","contentEncoding":"base64"}}}},"responses":{"200":{"description":"The OTLP batch was accepted.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtlpTraceResult"}}}},"400":{"description":"The request is malformed or fails validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller exceeded a route rate limit.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Ingestion is temporarily backpressured; exporters should retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"RetraceApiKey":{"type":"apiKey","in":"header","name":"x-retrace-key","description":"Retrace API key beginning with rt_."},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Retrace API key or Better Auth JWT","description":"Send Authorization: Bearer followed by an rt_ API key or web-session JWT."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key (max 255 characters) that ensures at-most-once semantics for mutating requests. If the same key is sent again within 24 hours, the server returns the original response without re-executing the operation. This allows AI agent retries to be safe against accidental duplication.","schema":{"type":"string","maxLength":255}}},"headers":{"RateLimit-Limit":{"description":"The maximum number of requests permitted in the current rate-limit window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"The number of requests remaining in the current rate-limit window.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"The number of seconds until the current rate-limit window resets.","schema":{"type":"integer","minimum":0}},"RateLimit-Policy":{"description":"The rate-limit policy expressed as an RFC 9110 structured field (e.g. '100;w=60').","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying after a 429 response.","schema":{"type":"integer","minimum":1}},"Deprecation":{"description":"RFC 8594 deprecation date in IMF-fixdate format indicating when the operation was deprecated.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594 sunset date in IMF-fixdate format indicating when the operation will be removed.","schema":{"type":"string"}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."},"code":{"type":"string","description":"Stable machine-readable error code when available."},"retryable":{"type":"boolean","description":"Whether retrying may succeed."}},"additionalProperties":true},"Health":{"type":"object","required":["status","service","version","timestamp","uptime"],"properties":{"status":{"type":"string","const":"ok"},"service":{"type":"string","const":"retrace-api"},"version":{"type":"string"},"commit":{"type":"string"},"buildTime":{"type":"string"},"deploymentId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"uptime":{"type":"number","minimum":0}},"additionalProperties":false},"Span":{"type":"object","required":["id","parent_id","span_type","name","started_at"],"properties":{"id":{"type":"string","format":"uuid"},"parent_id":{"type":["string","null"],"format":"uuid"},"span_type":{"type":"string","enum":["llm_call","tool_call","tool_result","reasoning","action","error","fork_point"]},"name":{"type":"string","maxLength":500},"model":{"type":"string","maxLength":100},"input":{},"output":{},"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"cost":{"type":"number"},"duration_ms":{"type":"integer"},"metadata":{"type":"object","additionalProperties":true},"agent_id":{"type":"string"},"parent_agent_id":{"type":"string"},"agent_role":{"type":"string"},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":"string","format":"date-time"},"error":{"type":"string"}},"additionalProperties":true},"Trace":{"type":"object","required":["id","status","startedAt"],"properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"status":{"type":"string","enum":["running","completed","failed"]},"input":{},"output":{},"totalTokens":{"type":"integer"},"totalCost":{"type":"string"},"totalDurationMs":{"type":"integer"},"spanCount":{"type":"integer"},"sessionId":{"type":["string","null"]},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"CreateTraceRequest":{"type":"object","required":["id","started_at"],"properties":{"id":{"type":"string","format":"uuid"},"project_id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":500},"input":{},"output":{},"status":{"type":"string","enum":["running","completed","failed"],"default":"running"},"total_tokens":{"type":"integer","default":0},"total_cost":{"type":"number","default":0},"total_duration_ms":{"type":"integer","default":0},"metadata":{"type":"object","additionalProperties":true},"session_id":{"type":"string","maxLength":100},"lossy":{"type":"boolean"},"terminated_early":{"type":"boolean"},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":"string","format":"date-time"},"spans":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/Span"}}},"additionalProperties":false},"FinishTraceRequest":{"type":"object","properties":{"status":{"type":"string","enum":["running","completed","failed"]},"output":{},"ended_at":{"type":"string","format":"date-time"},"total_tokens":{"type":"integer"},"total_cost":{"type":"number"},"total_duration_ms":{"type":"integer"},"lossy":{"type":"boolean"},"terminated_early":{"type":"boolean"}},"additionalProperties":false},"TraceDetail":{"allOf":[{"$ref":"#/components/schemas/Trace"},{"type":"object","required":["spans"],"properties":{"spans":{"type":"array","items":{"$ref":"#/components/schemas/Span"}},"causalOrder":{"type":"array","items":{"type":"string","format":"uuid"}},"concurrentGroups":{"type":"array","items":{"type":"array","items":{"type":"string","format":"uuid"}}}}}]},"TraceList":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Trace"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"type":"string"},"next_cursor":{"type":["string","null"],"description":"Opaque cursor to pass as the cursor query parameter for the next page. Null when no further results exist."},"has_more":{"type":"boolean","description":"Whether additional pages are available beyond this result set."}},"additionalProperties":false},"TraceCreateResult":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["created","resumed","updated"]}},"additionalProperties":true},"DeleteResult":{"type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean","const":true}},"additionalProperties":false},"Fork":{"type":"object","required":["id","traceId","forkPointSpanId","status"],"properties":{"id":{"type":"string","format":"uuid"},"traceId":{"type":"string","format":"uuid"},"forkPointSpanId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"description":{"type":["string","null"]},"modifiedInput":{},"status":{"type":"string","enum":["pending","replaying","completed","failed"]},"resultTraceId":{"type":["string","null"],"format":"uuid"}},"additionalProperties":true},"CreateForkRequest":{"type":"object","required":["trace_id","fork_point_span_id","modified_input"],"properties":{"trace_id":{"type":"string","format":"uuid"},"fork_point_span_id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":500},"description":{"type":"string"},"modified_input":{},"mock_outputs":{"type":"object","additionalProperties":true}},"additionalProperties":false},"ForkList":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Fork"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"next_cursor":{"type":["string","null"],"description":"Opaque cursor to pass as the cursor query parameter for the next page. Null when no further results exist."},"has_more":{"type":"boolean","description":"Whether additional pages are available beyond this result set."}},"additionalProperties":true},"ReplayResult":{"type":"object","required":["fork_id","status","mode"],"properties":{"fork_id":{"type":"string","format":"uuid"},"result_trace_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["replaying","completed","failed"]},"mode":{"type":"string","enum":["sdk","server"]},"execution_id":{"type":"string"},"byte_replayed":{"type":"integer"},"faithful_reexec":{"type":"integer"},"fidelity_caveats":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"SearchRequest":{"type":"object","required":["query"],"properties":{"query":{"type":"string","minLength":1},"filters":{"type":"object","properties":{"project_id":{"type":"string","format":"uuid"},"model":{"type":"string"},"span_type":{"type":"string","enum":["llm_call","tool_call","tool_result","reasoning","action","error","fork_point"]},"status":{"type":"string","enum":["running","completed","failed"]},"date_from":{"type":"string","format":"date-time"},"date_to":{"type":"string","format":"date-time"},"min_cost":{"type":"number"},"min_duration_ms":{"type":"integer"}},"additionalProperties":false},"limit":{"type":"integer","minimum":1,"maximum":100,"default":20},"offset":{"type":"integer","minimum":0,"default":0}},"additionalProperties":false},"SearchResult":{"type":"object","required":["spans"],"properties":{"spans":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Span"},{"type":"object","properties":{"similarity":{"type":"number","minimum":-1,"maximum":1}}}]}}},"additionalProperties":false},"EvaluationCriterion":{"type":"object","required":["name","description"],"properties":{"name":{"type":"string","maxLength":100},"description":{"type":"string","maxLength":1000},"weight":{"type":"number","minimum":0,"maximum":10,"default":1}},"additionalProperties":false},"CreateEvaluationRequest":{"type":"object","required":["name","criteria"],"properties":{"name":{"type":"string","maxLength":500},"description":{"type":"string"},"project_id":{"type":"string","format":"uuid"},"judge_model":{"type":"string","maxLength":100,"default":"gemini-2.5-flash"},"criteria":{"type":"array","minItems":1,"maxItems":10,"items":{"$ref":"#/components/schemas/EvaluationCriterion"}},"is_public":{"type":"boolean","default":false}},"additionalProperties":false},"Evaluation":{"type":"object","required":["id","name","judgeModel","criteria"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"projectId":{"type":["string","null"],"format":"uuid"},"judgeModel":{"type":"string"},"criteria":{"type":"array","items":{"$ref":"#/components/schemas/EvaluationCriterion"}},"isPublic":{"type":"boolean"}},"additionalProperties":true},"EvaluationList":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Evaluation"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"next_cursor":{"type":["string","null"],"description":"Opaque cursor to pass as the cursor query parameter for the next page. Null when no further results exist."},"has_more":{"type":"boolean","description":"Whether additional pages are available beyond this result set."}},"additionalProperties":true},"EvaluationDetail":{"allOf":[{"$ref":"#/components/schemas/Evaluation"},{"type":"object","required":["runs"],"properties":{"runs":{"type":"array","items":{"type":"object","additionalProperties":true}}}}]},"RunEvaluationRequest":{"type":"object","required":["trace_ids"],"properties":{"trace_ids":{"type":"array","minItems":1,"maxItems":50,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"judge_model":{"type":"string","maxLength":100}},"additionalProperties":false},"RunEvaluationResult":{"type":"object","required":["evaluation_id","runs","status"],"properties":{"evaluation_id":{"type":"string","format":"uuid"},"runs":{"type":"array","items":{"type":"object","required":["id","traceId","status"],"properties":{"id":{"type":"string","format":"uuid"},"traceId":{"type":"string","format":"uuid"},"status":{"type":"string"}}}},"status":{"type":"string","const":"running"}},"additionalProperties":false},"EvaluationGateRequest":{"type":"object","required":["trace_ids"],"properties":{"trace_ids":{"type":"array","minItems":1,"maxItems":50,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"threshold":{"type":"number","minimum":0,"maximum":1,"default":0.7},"fail_on_regression":{"type":"boolean","default":true},"baseline_run_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"additionalProperties":false},"EvaluationGateResult":{"type":"object","required":["passed"],"properties":{"passed":{"type":"boolean"},"score":{"type":"number","minimum":0,"maximum":1},"threshold":{"type":"number","minimum":0,"maximum":1},"regression":{"type":"boolean"},"runs":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"EnforcementCheckRequest":{"type":"object","required":["run_id"],"properties":{"run_id":{"type":"string","minLength":1,"maxLength":200},"project_id":{"type":"string","format":"uuid"},"trace_id":{"type":"string","format":"uuid"},"tool_name":{"type":"string","maxLength":200},"tool_args_hash":{"type":"string","maxLength":200},"model":{"type":"string","maxLength":200},"proposed_tokens":{"type":"integer","minimum":0},"proposed_usd":{"type":"number","minimum":0},"step_index":{"type":"integer","minimum":0}},"additionalProperties":false},"EnforcementDecision":{"type":"object","required":["verdict","policy_id","policy_type","reason"],"properties":{"verdict":{"type":"string","enum":["allow","block","hold"]},"policy_id":{"type":["string","null"],"format":"uuid"},"policy_type":{"type":["string","null"]},"reason":{"type":"string"},"hold_id":{"type":"string","format":"uuid"}},"additionalProperties":true},"OtlpTraceRequest":{"type":"object","required":["resourceSpans"],"properties":{"resourceSpans":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":true}}},"additionalProperties":false},"OtlpTraceResult":{"type":"object","properties":{"partialSuccess":{"type":"object","additionalProperties":true},"traces_created":{"type":"integer","minimum":0},"spans_ingested":{"type":"integer","minimum":0}},"additionalProperties":true},"Job":{"type":"object","required":["id","status","resource_type","resource_id","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","running","succeeded","failed"]},"resource_type":{"type":"string","description":"The type of resource this job operates on (e.g. 'fork', 'evaluation')."},"resource_id":{"type":"string","format":"uuid","description":"The UUID of the resource this job operates on."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"result":{"description":"The result payload when the job has succeeded."},"error":{"type":["string","null"],"description":"Error message when the job has failed."},"poll_after_seconds":{"type":"integer","minimum":1,"description":"Suggested number of seconds to wait before polling for status again."}},"additionalProperties":true},"BatchRequest":{"type":"object","required":["operations"],"properties":{"operations":{"type":"array","minItems":1,"maxItems":50,"uniqueItems":true,"description":"An array of sub-requests to execute. Each operation id must be unique within the batch.","items":{"type":"object","required":["id","method","path"],"properties":{"id":{"type":"string","description":"Caller-assigned unique identifier for correlating results."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for this sub-request."},"path":{"type":"string","description":"API path (e.g. /api/v1/traces)."},"body":{"description":"Optional request body for POST/PUT/PATCH operations."}},"additionalProperties":false}}},"additionalProperties":false},"BatchResponse":{"type":"object","required":["results"],"properties":{"results":{"type":"array","items":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string","description":"The caller-assigned id from the request."},"status":{"type":"integer","description":"HTTP status code for this sub-request."},"body":{"description":"Response body for this sub-request."}},"additionalProperties":false}}},"additionalProperties":false}}}}