openapi: 3.1.0
info:
title: Laminar API
version: 1.0.0
description: Public HTTP API for ingesting and managing data in a Laminar project.
license:
name: Apache 2.0
identifier: Apache-2.0
servers:
- url: https://api.lmnr.ai
description: Laminar Cloud
security:
- projectApiKey: []
tags:
- name: Ingestion
description: Send telemetry data to Laminar.
- name: Traces
description: Update trace data after ingestion.
- name: SQL
description: Query project data with read-only SQL.
- name: Projects
description: Resolve project information.
- name: Datasets
description: Create, read, update, and delete datasets and add datapoints.
- name: Evaluations
description: Create evaluation runs and record their results.
- name: Labeling queues
description: Add items to labeling queues.
- name: Signals
description: Manage automated evaluations of project traces.
- name: LLM profiles
description: Configure the workspace LLM credentials and models the playground and self-hosted Signals run on.
paths:
/v1/traces:
post:
tags: [Ingestion]
summary: Ingest OpenTelemetry traces
description: Accepts an OTLP ExportTraceServiceRequest encoded as protobuf or OTLP JSON.
operationId: ingestTraces
security: [{ projectApiKey: [] }, { ingestApiKey: [] }]
requestBody:
required: true
content:
application/x-protobuf:
schema: { type: string, contentMediaType: application/x-protobuf }
application/json:
schema: { type: object, additionalProperties: true }
responses:
"200": { description: Trace batch accepted. }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"413": { $ref: "#/components/responses/PayloadTooLarge" }
"429": { description: Ingestion rate limit exceeded. }
/v1/spans:
post:
tags: [Ingestion]
summary: Create spans
description: Ingests a batch of spans using Laminar's JSON span format.
operationId: createSpans
security: [{ projectApiKey: [] }, { ingestApiKey: [] }]
requestBody:
required: true
content:
application/json:
schema:
type: array
items: { $ref: "#/components/schemas/CreateSpanRequest" }
responses:
"200":
description: Spans accepted.
content:
application/json:
schema:
type: array
items: { $ref: "#/components/schemas/CreateSpanResponse" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"413": { $ref: "#/components/responses/PayloadTooLarge" }
/v1/logs:
post:
tags: [Ingestion]
summary: Ingest OpenTelemetry logs
description: >-
Accepts an OTLP ExportLogsServiceRequest encoded as protobuf. JSON-encoded OTLP is not accepted.
This endpoint is in beta: ingested logs are stored in the `logs` table and can only be queried with SQL.
They are not shown anywhere in the Laminar UI, and Signals do not read them when analyzing traces.
operationId: ingestLogs
security: [{ projectApiKey: [] }, { ingestApiKey: [] }]
requestBody:
required: true
content:
application/x-protobuf:
schema: { type: string, contentMediaType: application/x-protobuf }
responses:
"200": { description: Log batch accepted. }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"413": { $ref: "#/components/responses/PayloadTooLarge" }
/v1/labeling_queues/{queue_id}/items:
post:
tags: [Labeling queues]
summary: Add labeling queue items
description: Adds items to a labeling queue, optionally deduplicating them with idempotency keys.
operationId: createLabelingQueueItems
security: [{ projectApiKey: [] }, { ingestApiKey: [] }]
parameters:
- { $ref: "#/components/parameters/QueueId" }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CreateLabelingQueueItemsRequest" }
responses:
"201":
description: Items created.
content:
application/json:
schema:
{ type: array, items: { $ref: "#/components/schemas/LabelingQueueItemResponse" } }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
/v1/sql/query:
post:
tags: [SQL]
summary: Query project data
description: Executes a validated, read-only SQL query scoped to the authenticated project.
operationId: executeSqlQuery
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/SqlQueryRequest" }
responses:
"200":
description: Query results.
content:
application/json:
schema: { $ref: "#/components/schemas/SqlQueryResponse" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"429": { description: SQL query rate limit exceeded. }
/v1/project:
get:
tags: [Projects]
summary: Get the current project
description: Returns the project ID associated with the supplied API key.
operationId: getCurrentProject
responses:
"200":
description: Current project.
content:
application/json:
schema:
type: object
required: [projectId]
properties:
projectId: { $ref: "#/components/schemas/Uuid" }
"401": { $ref: "#/components/responses/Unauthorized" }
/v1/datasets:
get:
tags: [Datasets]
summary: List datasets
description: Lists project datasets, optionally filtered by dataset ID or name.
operationId: listDatasets
parameters:
- { name: id, in: query, schema: { $ref: "#/components/schemas/Uuid" } }
- { name: name, in: query, schema: { type: string } }
responses:
"200":
description: Matching datasets.
content:
application/json:
schema: { type: array, items: { $ref: "#/components/schemas/Dataset" } }
"401": { $ref: "#/components/responses/Unauthorized" }
post:
tags: [Datasets]
summary: Create a dataset
description: Creates an empty dataset. Dataset names do not need to be unique.
operationId: createDataset
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/DatasetNameRequest" }
responses:
"201":
description: Dataset created.
content:
application/json:
schema: { $ref: "#/components/schemas/Dataset" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
/v1/datasets/{dataset_id}:
parameters:
- { $ref: "#/components/parameters/DatasetId" }
get:
tags: [Datasets]
summary: Get a dataset
description: Returns a dataset by its canonical ID.
operationId: getDataset
responses:
"200":
description: Dataset found.
content:
application/json:
schema: { $ref: "#/components/schemas/Dataset" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
patch:
tags: [Datasets]
summary: Update a dataset
description: Renames a dataset. Dataset names do not need to be unique.
operationId: updateDataset
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/DatasetNameRequest" }
responses:
"200":
description: Dataset updated.
content:
application/json:
schema: { $ref: "#/components/schemas/Dataset" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
delete:
tags: [Datasets]
summary: Delete a dataset
description: Deletes a dataset and its datapoints.
operationId: deleteDataset
responses:
"200":
description: Dataset deleted. Returns the deleted dataset.
content:
application/json:
schema: { $ref: "#/components/schemas/Dataset" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
/v1/datasets/datapoints:
get:
tags: [Datasets]
summary: List dataset datapoints
description: Returns a paginated page of datapoints from a dataset identified by ID or name.
operationId: listDatasetDatapoints
parameters:
- { name: datasetId, in: query, schema: { $ref: "#/components/schemas/Uuid" } }
- { name: datasetName, in: query, schema: { type: string } }
- { name: limit, in: query, required: true, schema: { type: integer, format: int64, minimum: 1, maximum: 1000 } }
- { name: offset, in: query, required: true, schema: { type: integer, format: int64, minimum: 0 } }
responses:
"200":
description: A page of datapoints.
content:
application/json:
schema: { $ref: "#/components/schemas/DatapointPage" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
post:
tags: [Datasets]
summary: Create dataset datapoints
description: Adds datapoints to a dataset and can optionally create the dataset when identified by name.
operationId: createDatasetDatapoints
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CreateDatapointsRequest" }
responses:
"200": { $ref: "#/components/responses/DatapointsCreated" }
"201": { $ref: "#/components/responses/DatapointsCreated" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
"409": { description: A dataset with the requested name already exists. }
/v1/signals:
post:
tags: [Signals]
summary: Create a Signal
description: |
Creates a Signal with the first server-managed configuration version.
`llmProfileId` and `model` are available only on self-hosted deployments. Provide both fields together. Laminar Cloud rejects them.
operationId: createSignal
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CreateSignalRequest" }
responses:
"201":
description: Signal created.
content:
application/json:
schema: { $ref: "#/components/schemas/Signal" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"409": { $ref: "#/components/responses/Conflict" }
get:
tags: [Signals]
summary: List Signals
description: Lists Signals in the project, optionally filtering by a name substring.
operationId: listSignals
parameters:
- name: name
in: query
schema: { type: string }
responses:
"200":
description: Project Signals.
content:
application/json:
schema: { $ref: "#/components/schemas/SignalList" }
"401": { $ref: "#/components/responses/Unauthorized" }
/v1/signals/{signal_id}:
parameters:
- { $ref: "#/components/parameters/SignalId" }
get:
tags: [Signals]
summary: Get a Signal
description: Returns a Signal in the authenticated project.
operationId: getSignal
responses:
"200":
description: Signal details.
content:
application/json:
schema: { $ref: "#/components/schemas/Signal" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
patch:
tags: [Signals]
summary: Update a Signal
description: |
Updates a Signal. An update that changes the effective Signal configuration increments its server-managed version.
`llmProfileId` and `model` are available only on self-hosted deployments. Provide both fields together to change the Signal's LLM route. Laminar Cloud rejects them.
operationId: updateSignal
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UpdateSignalRequest" }
responses:
"200":
description: Signal updated.
content:
application/json:
schema: { $ref: "#/components/schemas/Signal" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
"409": { $ref: "#/components/responses/Conflict" }
delete:
tags: [Signals]
summary: Delete a Signal
description: |
Deletes a Signal and returns its final state.
Deleting a Signal also deletes all of its alerts and events and is irreversible. We recommend disabling the Signal instead. You can disable it from the UI or through the [Update a Signal](/api-reference/signals/update-a-signal) endpoint by setting `disabled` to `true`.
operationId: deleteSignal
responses:
"200":
description: Signal deleted.
content:
application/json:
schema: { $ref: "#/components/schemas/Signal" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
/v1/llm-profiles:
get:
tags: [LLM profiles]
summary: List LLM profiles
description: |
Lists every LLM profile in the authenticated project's workspace.
operationId: listLlmProfiles
responses:
"200":
description: Workspace LLM profiles. Secret values are masked.
content:
application/json:
schema: { $ref: "#/components/schemas/LlmProfileList" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
post:
tags: [LLM profiles]
summary: Create an LLM profile
description: |
Creates an LLM profile in the authenticated project's workspace.
Secrets are accepted as plaintext over TLS, stored encrypted, and never returned unmasked.
operationId: createLlmProfile
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CreateLlmProfileRequest" }
responses:
"200":
description: LLM profile created. Secret values are masked.
content:
application/json:
schema: { $ref: "#/components/schemas/LlmProfile" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
"409": { $ref: "#/components/responses/Conflict" }
/v1/llm-profiles/{profile_id}:
parameters:
- { $ref: "#/components/parameters/LlmProfileId" }
get:
tags: [LLM profiles]
summary: Get an LLM profile
description: |
Returns an LLM profile from the authenticated project's workspace. Secret values are masked.
operationId: getLlmProfile
responses:
"200":
description: LLM profile details.
content:
application/json:
schema: { $ref: "#/components/schemas/LlmProfile" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
patch:
tags: [LLM profiles]
summary: Update an LLM profile
description: |
Updates an LLM profile. Omitted fields retain their stored values, `models` replaces the complete model list, a supplied `config` replaces the whole stored config object, and supplied secrets are merged with stored secrets.
Removing a model used by a Signal returns `409 Conflict`.
operationId: updateLlmProfile
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UpdateLlmProfileRequest" }
responses:
"200":
description: LLM profile updated. Secret values are masked.
content:
application/json:
schema: { $ref: "#/components/schemas/LlmProfile" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
"409": { $ref: "#/components/responses/Conflict" }
delete:
tags: [LLM profiles]
summary: Delete an LLM profile
description: |
Deletes an LLM profile and returns its final state.
A profile used by a Signal cannot be deleted. The API returns `409 Conflict` until every Signal stops using it.
operationId: deleteLlmProfile
responses:
"200":
description: LLM profile deleted. Secret values are masked.
content:
application/json:
schema: { $ref: "#/components/schemas/LlmProfile" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
"409": { $ref: "#/components/responses/Conflict" }
/v1/evals:
post:
tags: [Evaluations]
summary: Create an evaluation
description: Creates an evaluation run, generating a name when none is supplied.
operationId: createEvaluation
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CreateEvaluationRequest" }
responses:
"200":
description: Evaluation created.
content:
application/json:
schema: { $ref: "#/components/schemas/Evaluation" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
/v1/evals/{eval_id}:
post:
tags: [Evaluations]
summary: Update an evaluation
description: Updates an evaluation's name and/or metadata; omitted fields remain unchanged.
operationId: updateEvaluation
parameters:
- { $ref: "#/components/parameters/EvaluationId" }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UpdateEvaluationRequest" }
responses:
"200":
description: Evaluation updated.
content:
application/json:
schema: { $ref: "#/components/schemas/Evaluation" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
"404": { $ref: "#/components/responses/NotFound" }
/v1/evals/{eval_id}/datapoints:
post:
tags: [Evaluations]
summary: Add evaluation datapoints
description: Adds result datapoints to an evaluation run.
operationId: createEvaluationDatapoints
parameters:
- { $ref: "#/components/parameters/EvaluationId" }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CreateEvaluationDatapointsRequest" }
responses:
"200":
description: Datapoints added; returns the evaluation ID.
content:
application/json:
schema: { $ref: "#/components/schemas/Uuid" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
/v1/evals/{eval_id}/datapoints/{datapoint_id}:
post:
tags: [Evaluations]
summary: Update an evaluation datapoint
description: Updates a datapoint's executor output, scores, and optional trace association.
operationId: updateEvaluationDatapoint
parameters:
- { $ref: "#/components/parameters/EvaluationId" }
- { $ref: "#/components/parameters/DatapointId" }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UpdateEvaluationDatapointRequest" }
responses:
"200":
description: Datapoint updated; returns the datapoint ID.
content:
application/json:
schema: { $ref: "#/components/schemas/Uuid" }
"400": { $ref: "#/components/responses/BadRequest" }
"401": { $ref: "#/components/responses/Unauthorized" }
components:
securitySchemes:
projectApiKey:
type: http
scheme: bearer
bearerFormat: Project API key
description: A Laminar project API key.
ingestApiKey:
type: http
scheme: bearer
bearerFormat: Ingest-only API key
description: A project API key restricted to ingestion operations.
parameters:
DatasetId:
name: dataset_id
in: path
required: true
schema: { $ref: "#/components/schemas/Uuid" }
QueueId:
name: queue_id
in: path
required: true
schema: { $ref: "#/components/schemas/Uuid" }
EvaluationId:
name: eval_id
in: path
required: true
schema: { $ref: "#/components/schemas/Uuid" }
DatapointId:
name: datapoint_id
in: path
required: true
schema: { $ref: "#/components/schemas/Uuid" }
SignalId:
name: signal_id
in: path
required: true
schema: { $ref: "#/components/schemas/Uuid" }
LlmProfileId:
name: profile_id
in: path
required: true
schema: { $ref: "#/components/schemas/Uuid" }
responses:
Success: { description: Request completed successfully. }
BadRequest:
description: Invalid request.
content:
application/json:
schema: { $ref: "#/components/schemas/Error" }
Unauthorized:
description: Missing or invalid API key.
NotFound:
description: The requested resource was not found in this project.
content:
application/json:
schema: { $ref: "#/components/schemas/Error" }
PayloadTooLarge: { description: The request exceeds the configured HTTP payload limit. }
Conflict:
description: A resource with the requested name already exists.
content:
application/json:
schema: { $ref: "#/components/schemas/Error" }
DatapointsCreated:
description: Datapoints created; status 201 means the dataset was also created.
content:
application/json:
schema: { $ref: "#/components/schemas/CreateDatapointsResponse" }
schemas:
Uuid: { type: string, format: uuid }
JsonValue: {}
Error:
oneOf:
- { type: object, properties: { error: { type: string } }, required: [error] }
- { type: string }
CreateSpanRequest:
type: object
required: [name, startTime, endTime, traceId, spanId]
properties:
name: { type: string }
spanType:
type: [string, "null"]
description: "Note: The backend may still accept `PIPELINE` and `HUMAN_EVALUATOR`, but they are undocumented, and should not be used."
enum: [DEFAULT, LLM, EXECUTOR, EVALUATOR, EVALUATION, TOOL, CACHED, null]
startTime: { type: string, format: date-time }
endTime: { type: string, format: date-time }
input: { $ref: "#/components/schemas/JsonValue" }
output: { $ref: "#/components/schemas/JsonValue" }
attributes: { type: [object, "null"], additionalProperties: true }
traceId: { $ref: "#/components/schemas/Uuid" }
spanId: { $ref: "#/components/schemas/Uuid" }
parentSpanId: { oneOf: [{ $ref: "#/components/schemas/Uuid" }, { type: "null" }] }
CreateSpanResponse:
type: object
required: [spanId, traceId]
properties:
spanId: { $ref: "#/components/schemas/Uuid" }
traceId: { $ref: "#/components/schemas/Uuid" }
CreateLabelingQueueItemsRequest:
type: object
required: [items]
properties:
items:
type: array
minItems: 1
items: { $ref: "#/components/schemas/LabelingQueueItemRequest" }
LabelingQueueItemRequest:
type: object
required: [data, target]
properties:
data: { $ref: "#/components/schemas/JsonValue" }
target: { $ref: "#/components/schemas/JsonValue" }
metadata: { type: object, additionalProperties: true, default: {} }
idempotencyKey: { type: [string, "null"] }
LabelingQueueItemResponse:
type: object
required: [id, createdAt]
properties:
id: { $ref: "#/components/schemas/Uuid" }
createdAt: { type: string, format: date-time }
SqlQueryRequest:
type: object
required: [query]
properties:
query: { type: string }
parameters: { type: object, additionalProperties: true, default: {} }
SqlQueryResponse:
type: object
required: [data]
properties:
data: { type: array, items: { $ref: "#/components/schemas/JsonValue" } }
DatasetNameRequest:
type: object
required: [name]
properties:
name:
type: string
minLength: 1
description: Dataset name. Names are stored as supplied and do not need to be unique.
Dataset:
type: object
required: [id, name, projectId, createdAt]
properties:
id: { $ref: "#/components/schemas/Uuid" }
name: { type: string }
projectId: { $ref: "#/components/schemas/Uuid" }
createdAt: { type: string, format: date-time }
Datapoint:
type: object
required: [id, datasetId, data, metadata, createdAt]
properties:
id: { $ref: "#/components/schemas/Uuid" }
datasetId: { $ref: "#/components/schemas/Uuid" }
data: { $ref: "#/components/schemas/JsonValue" }
target: { $ref: "#/components/schemas/JsonValue" }
metadata: { type: object, additionalProperties: true }
createdAt: { type: string, format: date-time }
DatapointPage:
type: object
required: [totalCount, items, anyInProject]
properties:
totalCount: { type: integer, format: int64 }
items: { type: array, items: { $ref: "#/components/schemas/Datapoint" } }
anyInProject: { type: boolean }
NewDatapoint:
type: object
required: [data]
properties:
id: { oneOf: [{ $ref: "#/components/schemas/Uuid" }, { type: "null" }] }
data: { $ref: "#/components/schemas/JsonValue" }
target: { $ref: "#/components/schemas/JsonValue" }
metadata: { type: object, additionalProperties: true, default: {} }
CreateDatapointsRequest:
type: object
required: [datapoints]
description: Supply exactly one of datasetId or datasetName.
properties:
datasetId: { $ref: "#/components/schemas/Uuid" }
datasetName: { type: string }
datapoints: { type: array, items: { $ref: "#/components/schemas/NewDatapoint" } }
createDataset: { type: boolean, default: false }
oneOf:
- { required: [datasetId] }
- { required: [datasetName] }
CreateDatapointsResponse:
type: object
required: [message, datasetId, count, datapointInfo]
properties:
message: { type: string }
datasetId: { $ref: "#/components/schemas/Uuid" }
count: { type: integer }
datapointInfo:
type: array
items:
type: object
required: [id, createdAt]
properties:
id: { $ref: "#/components/schemas/Uuid" }
createdAt: { type: string, format: date-time }
SignalTrigger:
oneOf:
- type: object
required: [type]
properties:
type: { type: string, const: rootSpanFinished }
- type: object
required: [type, spanNames]
properties:
type: { type: string, const: spanName }
spanNames:
type: array
minItems: 1
items: { type: string }
SignalFilter:
type: object
required: [column, operator, value]
properties:
column:
type: string
enum: [total_token_count, status, span_names, tags]
operator:
type: string
enum: [eq, ne, gt, gte, lt, lte, includes, not_includes]
value: { $ref: "#/components/schemas/JsonValue" }
description: Operators and value shapes are validated for the selected column.
SignalDefinitionFields:
type: object
properties:
name: { type: string, maxLength: 255 }
prompt: { type: string }
structuredOutput:
type: object
additionalProperties: true
description: JSON Schema for the Signal's structured result.
sampleRate:
type: [integer, "null"]
minimum: 1
maximum: 95
description: Percentage of matching traces to sample; null clears sampling on update.
disabled: { type: boolean }
trigger: { $ref: "#/components/schemas/SignalTrigger" }
filters:
type: array
items: { $ref: "#/components/schemas/SignalFilter" }
mode: { type: string, enum: [batch, realtime] }
llmProfileId:
oneOf:
- { $ref: "#/components/schemas/Uuid" }
- { type: "null" }
description: Self-hosted only. Workspace LLM profile used to evaluate the Signal. Provide with `model`; omit both fields on update to keep the existing route.
model:
type: [string, "null"]
description: Self-hosted only. Model selected from `llmProfileId`. Provide both fields together.
CreateSignalRequest:
allOf:
- { $ref: "#/components/schemas/SignalDefinitionFields" }
- type: object
required: [name, prompt, structuredOutput]
UpdateSignalRequest:
$ref: "#/components/schemas/SignalDefinitionFields"
Signal:
allOf:
- { $ref: "#/components/schemas/SignalDefinitionFields" }
- type: object
required:
[
id,
projectId,
name,
prompt,
structuredOutput,
sampleRate,
disabled,
createdAt,
trigger,
filters,
mode,
version,
llmProfileId,
llmProfileName,
model,
]
properties:
id: { $ref: "#/components/schemas/Uuid" }
projectId: { $ref: "#/components/schemas/Uuid" }
createdAt: { type: string, format: date-time }
version:
type: integer
format: int32
minimum: 1
readOnly: true
description: Server-managed version of the Signal configuration.
llmProfileName:
type: [string, "null"]
readOnly: true
description: Display name of the selected workspace LLM profile.
SignalList:
type: object
required: [signals]
properties:
signals:
type: array
items: { $ref: "#/components/schemas/Signal" }
LlmProfileProvider:
type: string
enum:
[
openai_completions,
openai_responses,
anthropic,
gemini,
groq,
mistral,
bedrock,
azure_chat_completions,
azure_responses,
azure_anthropic,
custom,
custom_responses,
]
LlmProfileAuth:
oneOf:
- type: object
required: [type]
properties:
type: { type: string, const: api_key }
- type: object
required: [type, accessKeyId]
properties:
type: { type: string, const: aws_keys }
accessKeyId: { type: string, maxLength: 256 }
- type: object
required: [type]
properties:
type: { type: string, const: bearer_token }
LlmProfileConfig:
type: object
properties:
auth: { $ref: "#/components/schemas/LlmProfileAuth" }
region: { type: string, maxLength: 64 }
resourceId: { type: string, maxLength: 256 }
baseUrl: { type: string, format: uri }
apiVersion: { type: string, maxLength: 64 }
headerNames:
type: array
maxItems: 32
uniqueItems: true
items: { type: string, maxLength: 256 }
description: Provider-specific non-secret configuration. Azure requires exactly one of `resourceId` or `baseUrl`; Bedrock requires `region`; custom providers require `baseUrl`.
LlmProfileSecretsInput:
type: object
writeOnly: true
properties:
apiKey: { type: string, format: password, maxLength: 8192 }
secretAccessKey: { type: string, format: password, maxLength: 8192 }
token: { type: string, format: password, maxLength: 8192 }
headers:
type: object
additionalProperties: { type: string, format: password, maxLength: 8192 }
description: Plaintext credentials. Required fields depend on the provider and authentication type.
LlmProfileSecrets:
type: object
readOnly: true
required: [apiKey, secretAccessKey, token, headers]
properties:
apiKey: { type: [string, "null"], description: Masked API key. }
secretAccessKey: { type: [string, "null"], description: Masked AWS secret access key. }
token: { type: [string, "null"], description: Masked bearer token. }
headers:
type: array
items: { type: string }
description: Names of stored custom headers; values are never returned.
CreateLlmProfileRequest:
type: object
required: [name, provider, models]
properties:
name: { type: string, maxLength: 255 }
provider: { $ref: "#/components/schemas/LlmProfileProvider" }
config: { $ref: "#/components/schemas/LlmProfileConfig" }
secrets: { $ref: "#/components/schemas/LlmProfileSecretsInput" }
models:
type: array
minItems: 1
maxItems: 64
uniqueItems: true
items: { type: string, maxLength: 256 }
UpdateLlmProfileRequest:
type: object
properties:
name: { type: string, maxLength: 255 }
provider:
allOf:
- { $ref: "#/components/schemas/LlmProfileProvider" }
description: When changing the provider, `config` is required.
config: { $ref: "#/components/schemas/LlmProfileConfig" }
secrets:
allOf:
- { $ref: "#/components/schemas/LlmProfileSecretsInput" }
description: Supplied values replace matching secrets; omitted values remain unchanged.
models:
type: array
minItems: 1
maxItems: 64
uniqueItems: true
items: { type: string, maxLength: 256 }
description: Replaces the complete model list when supplied.
LlmProfile:
type: object
required: [id, workspaceId, name, provider, config, models, secrets, createdAt, updatedAt]
properties:
id: { $ref: "#/components/schemas/Uuid" }
workspaceId: { $ref: "#/components/schemas/Uuid" }
name: { type: string }
provider: { $ref: "#/components/schemas/LlmProfileProvider" }
config: { $ref: "#/components/schemas/LlmProfileConfig" }
models:
type: array
items: { type: string }
secrets: { $ref: "#/components/schemas/LlmProfileSecrets" }
createdAt: { type: string, format: date-time }
updatedAt: { type: string, format: date-time }
LlmProfileList:
type: object
required: [llmProfiles]
properties:
llmProfiles:
type: array
items: { $ref: "#/components/schemas/LlmProfile" }
CreateEvaluationRequest:
type: object
properties:
name: { type: [string, "null"] }
groupName: { type: [string, "null"], default: default }
metadata: { $ref: "#/components/schemas/JsonValue" }
UpdateEvaluationRequest:
type: object
properties:
name: { type: [string, "null"] }
metadata:
description: Replaces the complete evaluation metadata object when supplied.
$ref: "#/components/schemas/JsonValue"
Evaluation:
type: object
required: [id, createdAt, name, projectId, groupId]
properties:
id: { $ref: "#/components/schemas/Uuid" }
createdAt: { type: string, format: date-time }
name: { type: string }
projectId: { $ref: "#/components/schemas/Uuid" }
groupId: { type: string }
metadata: { $ref: "#/components/schemas/JsonValue" }
CreateEvaluationDatapointsRequest:
type: object
required: [points]
properties:
groupName: { type: [string, "null"], default: default }
points:
type: array
items: { $ref: "#/components/schemas/EvaluationDatapoint" }
EvaluationDatapoint:
type: object
required: [data]
properties:
data: { $ref: "#/components/schemas/JsonValue" }
index: { type: integer, format: int32, default: 0 }
id: { $ref: "#/components/schemas/Uuid" }
target: { $ref: "#/components/schemas/JsonValue" }
metadata: { type: [object, "null"], additionalProperties: true }
executorOutput: { $ref: "#/components/schemas/JsonValue" }
traceId: { $ref: "#/components/schemas/Uuid" }
scores:
type: object
additionalProperties: { type: [number, "null"], format: double }
datasetLink:
oneOf:
- { $ref: "#/components/schemas/EvaluationDatasetLink" }
- { type: "null" }
EvaluationDatasetLink:
type: object
required: [datasetId, datapointId, createdAt]
properties:
datasetId: { $ref: "#/components/schemas/Uuid" }
datapointId: { $ref: "#/components/schemas/Uuid" }
createdAt: { type: string, format: date-time }
UpdateEvaluationDatapointRequest:
type: object
required: [scores]
properties:
executorOutput: { $ref: "#/components/schemas/JsonValue" }
scores:
type: object
additionalProperties: { type: [number, "null"], format: double }
traceId: { oneOf: [{ $ref: "#/components/schemas/Uuid" }, { type: "null" }] }