{"openapi":"3.1.0","info":{"title":"Roark Analytics API","description":"The Roark Analytics API gives you access to the same API that powers the award winning Roark Analytics platform.","version":"1.0.0"},"components":{"securitySchemes":{"Bearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"]},"version":{"type":"string"},"timestamp":{"type":"string"}},"required":["status","version","timestamp"],"description":"Health check response payload","example":{"status":"healthy","version":"1.0.0","timestamp":"2026-05-18T09:44:40.971Z"}},"ErrorResponse":{"type":"object","properties":{"type":{"type":"string","enum":["validation","authentication","forbidden","not_found","conflict","payment_required","rate_limit","internal"],"description":"The error type category","examples":["validation","authentication"]},"code":{"type":"string","description":"Machine-readable error code identifier","examples":["invalid_parameter","missing_required_field","unauthorized"]},"message":{"type":"string","description":"Human-readable error message","examples":["The request was invalid","Authentication required"]},"param":{"type":"string","description":"The parameter that caused the error (if applicable)","examples":["email","user_id"]},"details":{"description":"Additional error context information"}},"required":["type","code","message"]},"AgentEndpointDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Agent endpoint ID"},"agentId":{"type":"string","format":"uuid","description":"Agent ID this endpoint belongs to"},"type":{"type":"string","enum":["PHONE","WEBSOCKET","LIVEKIT","SMALL_WEBRTC","ELEVENLABS_WS","KORE","GOOGLE_CES","DAILY"],"description":"Agent endpoint type (PHONE, WEBSOCKET, LIVEKIT, SMALL_WEBRTC, or ELEVENLABS_WS)"},"value":{"type":"string","description":"Agent endpoint value (phone number, URL, etc.)"},"environment":{"type":"string","description":"Agent endpoint environment"},"direction":{"type":"string","enum":["INCOMING","OUTGOING","INCOMING_AND_OUTGOING"],"description":"Agent endpoint direction (INCOMING, OUTGOING, INCOMING_AND_OUTGOING)"},"outboundDialType":{"type":"string","enum":["NONE","HTTP_REQUEST"],"description":"Outbound dial type (NONE or HTTP_REQUEST)"},"outboundDialHttpRequestDefinitionId":{"type":["string","null"],"format":"uuid","description":"ID of the linked HTTP request definition for outbound dialing"},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","agentId","type","value","environment","direction","outboundDialType","outboundDialHttpRequestDefinitionId","createdAt","updatedAt"],"description":"Detailed agent endpoint response"},"CreateAgentEndpointInput":{"type":"object","properties":{"agentId":{"type":"string","format":"uuid","description":"Agent ID to associate this endpoint with"},"value":{"type":"string","description":"Phone number in E.164 format (e.g., +12345678900)"},"environment":{"type":"string","default":"production","description":"Environment name (default: production)"},"direction":{"type":"string","enum":["INCOMING","OUTGOING","INCOMING_AND_OUTGOING"],"description":"Call direction: INCOMING, OUTGOING, or INCOMING_AND_OUTGOING"},"outboundDialType":{"type":"string","enum":["NONE","HTTP_REQUEST"],"default":"NONE","description":"Outbound dial type: NONE or HTTP_REQUEST (default: NONE)"},"outboundDialHttpRequestDefinitionId":{"type":["string","null"],"format":"uuid","description":"ID of the HTTP request definition for outbound dialing (required when outboundDialType is HTTP_REQUEST)"}},"required":["agentId","value","direction"],"description":"Input for creating an agent endpoint"},"UpdateAgentEndpointInput":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name"},"outboundDialType":{"type":"string","enum":["NONE","HTTP_REQUEST"],"description":"Outbound dial type: NONE or HTTP_REQUEST"},"outboundDialHttpRequestDefinitionId":{"type":["string","null"],"format":"uuid","description":"ID of the HTTP request definition for outbound dialing"}},"description":"Input for updating an agent endpoint"},"GetAgentPromptsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AgentPromptResponse"}}},"required":["data"]},"AgentPromptResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Prompt lineage ID (its own version history)."},"source":{"type":"string","enum":["USER","RETELL_INTEGRATION","VAPI_INTEGRATION","ELEVEN_LABS_INTEGRATION","BLAND_INTEGRATION","PIPECAT_CLOUD_INTEGRATION","PIPECAT_SELF_HOSTED_INTEGRATION","LIVEKIT_SELF_HOSTED_INTEGRATION","API","CONFIG","API_MANAGED"],"description":"Where this prompt came from: USER (edited in the app), API (provided via the API or on calls), CONFIG (managed by config-as-code), or a provider integration."},"prompt":{"type":"string","description":"Current prompt content (the latest version)."},"updatedAt":{"type":"string","description":"When the current version was recorded (ISO 8601)."},"createdAt":{"type":"string","description":"When this prompt lineage was first created (ISO 8601)."}},"required":["id","source","prompt","updatedAt","createdAt"],"description":"A prompt lineage on an agent."},"GetAgentPromptVersionsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AgentPromptVersionResponse"}}},"required":["data"]},"AgentPromptVersionResponse":{"type":"object","properties":{"versionNumber":{"type":"integer","description":"Version number: 1-based and increasing."},"prompt":{"type":"string","description":"Prompt content at this version."},"createdAt":{"type":"string","description":"When this version was recorded (ISO 8601)."}},"required":["versionNumber","prompt","createdAt"]},"SetAgentPromptResponse":{"type":"object","properties":{"promptId":{"type":"string","format":"uuid","description":"The ID of the API-managed prompt lineage."},"versionNumber":{"type":"integer","description":"The current version number after the set."},"changed":{"type":"boolean","description":"True if a new version was appended; false if the content matched the current version (no-op)."}},"required":["promptId","versionNumber","changed"]},"SetAgentPromptInput":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"The prompt content to set."}},"required":["prompt"]},"CallCreate":{"type":"object","properties":{"recordingUrl":{"type":"string","format":"uri","description":"URL of source recording (must be an accessible WAV, MP3, MP4, or OGG file). Can be a signed URL."},"stereoRecordingUrl":{"type":"string","format":"uri","description":"URL of source stereo recording. Must be accessible. Can be a signed URL. Supported formats: WAV, MP3, MP4, OGG."},"startedAt":{"type":"string","description":"When the call started (ISO 8601 format)"},"interfaceType":{"type":"string","enum":["PHONE","WEB"],"description":"Interface type of the call (PHONE or WEB)"},"callDirection":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the call (INBOUND or OUTBOUND)"},"endedStatus":{"type":"string","enum":["PARTICIPANTS_DID_NOT_SPEAK","AGENT_DID_NOT_ANSWER","AGENT_DID_NOT_SPEAK","AGENT_STOPPED_SPEAKING","AGENT_ENDED_CALL","AGENT_TRANSFERRED_CALL","AGENT_BUSY","AGENT_ERROR","CUSTOMER_ENDED_CALL","VOICE_MAIL_REACHED","SILENCE_TIME_OUT","PHONE_CALL_PROVIDER_CONNECTION_ERROR","CUSTOMER_DID_NOT_ANSWER","CUSTOMER_DID_NOT_SPEAK","CUSTOMER_STOPPED_SPEAKING","CUSTOMER_BUSY","DIAL_ERROR","MAX_DURATION_REACHED","UNKNOWN"],"description":"High-level call end status, indicating how the call terminated"},"transcript":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TranscriptEntryAgent"},{"$ref":"#/components/schemas/TranscriptEntryCustomer"}]},"description":"List of transcript entries made during the call"},"toolInvocations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the tool that was invoked"},"description":{"type":"string","description":"Description of when the tool should be invoked"},"parameters":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"description":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean"]},"value":{}}},{}]},"description":"Parameters provided to the tool during invocation"},"result":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{}}],"description":"Result returned by the tool after execution. Can be a string or a JSON object"},"startOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647,"description":"Offset in milliseconds from the start of the call when the tool was invoked"},"endOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647,"description":"Offset in milliseconds from the start of the call when the tool execution completed. Used to calculate duration of the tool execution"},"agent":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"The Roark ID of the agent"},"customId":{"type":"string","description":"The custom ID set on the agent"}},"description":"Metadata about the agent that invoked this tool - used to match which agent from the agents array this tool invocation belongs to"}},"required":["name","parameters","result","startOffsetMs"]},"description":"List of tool invocations made during the call"},"properties":{"type":"object","additionalProperties":{},"description":"Custom properties to include with the call. These can be used for filtering and will show in the call details page"},"vapiCallId":{"type":"string","format":"uuid","description":"The Vapi call ID (UUID) to link this call with OpenTelemetry trace data from Vapi. Used for matching calls with OTEL traces."},"livekitRoomId":{"type":"string","maxLength":255,"description":"The LiveKit Cloud room ID to link this call with OpenTelemetry trace data from LiveKit. Used for matching calls with OTEL traces."},"externalId":{"type":"string","maxLength":255,"description":"A stable identifier from your own system (e.g. session ID, conversation ID) used to correlate this call with OpenTelemetry traces. Set the same value as a `roark.external_id` span or resource attribute on your traces and the matching trace will be linked automatically. Must be unique within a project."},"agent":{"allOf":[{"anyOf":[{"$ref":"#/components/schemas/AgentIdentificationByRoarkId"},{"$ref":"#/components/schemas/AgentIdentificationByName"},{"$ref":"#/components/schemas/AgentIdentificationByCustomId"}]},{"type":"object","properties":{"endpoint":{"anyOf":[{"$ref":"#/components/schemas/AgentEndpointById"},{"$ref":"#/components/schemas/AgentEndpointByValue"}],"description":"Endpoint configuration for this agent (optional)"},"prompt":{"type":"object","properties":{"resolvedPrompt":{"type":"string","description":"The agent's system prompt used during this call"}},"required":["resolvedPrompt"],"description":"Agent's prompt configuration (optional)"}}}],"description":"Single agent participating in the call. Use this for simpler API when you have only one agent."},"agents":{"type":"array","items":{"allOf":[{"anyOf":[{"$ref":"#/components/schemas/AgentIdentificationByRoarkId"},{"$ref":"#/components/schemas/AgentIdentificationByName"},{"$ref":"#/components/schemas/AgentIdentificationByCustomId"}]},{"type":"object","properties":{"endpoint":{"anyOf":[{"$ref":"#/components/schemas/AgentEndpointById"},{"$ref":"#/components/schemas/AgentEndpointByValue"}],"description":"Endpoint configuration for this agent (optional)"},"prompt":{"type":"object","properties":{"resolvedPrompt":{"type":"string","description":"The agent's system prompt used during this call"}},"required":["resolvedPrompt"],"description":"Agent's prompt configuration (optional)"}}}],"description":"Agent participating in the call with their endpoint and prompt"},"description":"Agents participating in the call. Each agent requires identification and prompt information."},"customer":{"type":"object","properties":{"label":{"type":["string","null"],"description":"Label to identify this customer in the transcript (e.g., \"speaker-01\", \"speaker-02\")"},"phoneNumberE164":{"type":["string","null"],"description":"Customer phone number in E.164 format (e.g., +14155551234)"}},"required":["phoneNumberE164"],"description":"Single customer participating in the call. Use this for simpler API when you have only one customer."},"customers":{"type":"array","items":{"type":"object","properties":{"label":{"type":["string","null"],"description":"Label to identify this customer in the transcript (e.g., \"speaker-01\", \"speaker-02\")"},"phoneNumberE164":{"type":["string","null"],"description":"Customer phone number in E.164 format (e.g., +14155551234)"}},"required":["phoneNumberE164"],"description":"Customer participating in the call"},"description":"Customers participating in the call."}},"required":["recordingUrl","startedAt","interfaceType","callDirection"],"description":"Call creation payload. Supports singular (agent/customer) or plural (agents/customers) formats."},"TranscriptEntryAgent":{"type":"object","properties":{"startOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647},"endOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647},"text":{"type":"string"},"languageCode":{"type":"string"},"payload":{"type":["object","null"],"additionalProperties":{}},"role":{"type":"string","const":"AGENT"},"agent":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"The Roark ID of the agent"},"customId":{"type":"string","description":"The custom ID set on the agent"}},"description":"Metadata about the agent that spoke this turn - used to match which agent from the `agents` array this transcript entry belongs to"}},"required":["startOffsetMs","endOffsetMs","text","role"]},"TranscriptEntryCustomer":{"type":"object","properties":{"startOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647},"endOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647},"text":{"type":"string"},"languageCode":{"type":"string"},"payload":{"type":["object","null"],"additionalProperties":{}},"role":{"type":"string","const":"CUSTOMER"},"customer":{"type":"object","properties":{"phoneNumberE164":{"type":"string","description":"The phone number of the customer in E.164 format, matching the `phoneNumberE164` field on the `customers` array when creating the call"},"label":{"type":"string","description":"Label matching the `label` field on the `customers` array when creating the call"}},"description":"Metadata about the customer that spoke this turn - used to match which customer from the `customers` array this transcript entry belongs to"}},"required":["startOffsetMs","endOffsetMs","text","role"]},"AgentIdentificationByRoarkId":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"Existing Roark agent ID"}},"required":["roarkId"]},"AgentIdentificationByName":{"type":"object","properties":{"name":{"type":"string","description":"Agent name"},"description":{"type":"string","description":"Agent description"},"customId":{"type":"string","description":"Agent custom ID"}},"required":["name"],"description":"Find existing by customId if provided, otherwise reuse exact project name match before creating"},"AgentIdentificationByCustomId":{"type":"object","properties":{"customId":{"type":"string","description":"Existing custom ID for a Roark agent"}},"required":["customId"]},"AgentEndpointById":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Existing Roark endpoint ID"}},"required":["id"]},"AgentEndpointByValue":{"type":"object","properties":{"value":{"type":"string","description":"Endpoint value (phone number in E.164 format or websocket URL)"},"type":{"type":"string","description":"Type of endpoint (phone or websocket)"},"direction":{"type":"string","description":"Call direction for this endpoint"}},"required":["value","type"],"description":"Lookup or create endpoint if one with these values does not exist"},"AppendToolInvocationsResponse":{"type":"object","properties":{"callId":{"type":"string","format":"uuid","description":"The call the tool invocations were attached to"},"added":{"type":"integer","description":"Number of tool invocations newly written"},"skipped":{"type":"integer","description":"Number of tool invocations skipped because an identical one (same tool and timing) already existed on the call"},"metricCollectionJob":{"oneOf":[{"$ref":"#/components/schemas/MetricCollectionJobResponse"},{"type":"null"}],"description":"The metric collection job triggered to (re)score the requested metrics, or null when no metrics were requested (or when scoring failed, see metricCollectionError). Track its id to fetch results from GET /v1/metric/collection-jobs/:jobId."},"metricCollectionError":{"type":["string","null"],"description":"Present (non-null) only when `metrics` were requested but the collection job could not be started (e.g. insufficient credits, or an unknown metric id). The tool invocations were still attached — retry scoring via POST /v1/metric/collection-jobs, or re-send this request (attaching is idempotent). Null on success or when no metrics were requested."}},"required":["callId","added","skipped","metricCollectionJob","metricCollectionError"],"description":"Result of appending tool invocations to a call."},"MetricCollectionJobResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the metric collection job"},"status":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","CANCELED"],"description":"Current status of the job"},"triggeredBy":{"type":"string","enum":["USER_MANUAL","USER_API","METRIC_POLICY","SIMULATION"],"description":"What triggered this job"},"totalItems":{"type":"integer","description":"Total number of call-metric pairs to process"},"completedItems":{"type":"integer","description":"Number of successfully completed items"},"failedItems":{"type":"integer","description":"Number of failed items"},"startedAt":{"type":["string","null"],"description":"When the job started processing"},"completedAt":{"type":["string","null"],"description":"When the job completed"},"errorMessage":{"type":["string","null"],"description":"Error message if the job failed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of the metric policies that triggered this job"},"createdAt":{"type":"string","description":"When the job was created"},"updatedAt":{"type":"string","description":"When the job was last updated"}},"required":["id","status","triggeredBy","totalItems","completedItems","failedItems","startedAt","completedAt","errorMessage","policyIds","createdAt","updatedAt"],"description":"A metric collection job that processes metrics for calls or chats"},"AppendToolInvocationsRequest":{"type":"object","properties":{"toolInvocations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the tool that was invoked"},"description":{"type":"string","description":"Description of when the tool should be invoked"},"parameters":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"description":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean"]},"value":{}}},{}]},"description":"Parameters provided to the tool during invocation"},"result":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{}}],"description":"Result returned by the tool after execution. Can be a string or a JSON object"},"startOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647,"description":"Offset in milliseconds from the start of the call when the tool was invoked"},"endOffsetMs":{"type":"integer","minimum":0,"maximum":2147483647,"description":"Offset in milliseconds from the start of the call when the tool execution completed. Used to calculate duration of the tool execution"},"agent":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"The Roark ID of the agent"},"customId":{"type":"string","description":"The custom ID set on the agent"}},"description":"Metadata about the agent that invoked this tool - used to match which agent from the agents array this tool invocation belongs to"}},"required":["name","parameters","result","startOffsetMs"]},"minItems":1,"maxItems":500,"description":"Tool invocations that fired during the call, to attach to it. Max 500 per request. Re-sending an invocation already present on the call (same tool name and timing) is skipped, so retries are safe."},"metrics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"maxItems":20,"description":"Optional. Metric definitions to (re)score on this call after the tool invocations are attached, e.g. the Tool Invocation Analysis metrics. Triggers a metric collection job (billed, credit-gated) and requires the 'metric:create' permission. Omit to attach tools without scoring. Max 20."}},"required":["toolInvocations"],"description":"Attach tool invocations to an existing call, optionally (re)scoring metrics over them."},"ChatCreate":{"type":"object","properties":{"startTimestamp":{"type":"string","description":"When the chat started (ISO 8601 format)"},"endTimestamp":{"type":"string","description":"When the chat ended (ISO 8601 format)"},"messages":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/ChatMessageAgent"},{"$ref":"#/components/schemas/ChatMessageCustomer"}]},"description":"Ordered list of messages exchanged during the chat"},"toolInvocations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the tool that was invoked"},"description":{"type":"string","description":"Description of when the tool should be invoked"},"parameters":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"description":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean"]},"value":{}}},{}]},"description":"Parameters provided to the tool during invocation"},"result":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{}}],"description":"Result returned by the tool after execution. Can be a string or a JSON object"},"startTimestamp":{"type":"string","description":"When the tool was invoked (ISO 8601). Must fall within the chat time range."},"endTimestamp":{"type":"string","description":"When the tool execution completed (ISO 8601). Used to calculate duration of the tool execution."},"agent":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"The Roark ID of the agent"},"customId":{"type":"string","description":"The custom ID set on the agent"}},"description":"Metadata about the agent that invoked this tool - used to match which agent from the agents array this tool invocation belongs to"}},"required":["name","parameters","result","startTimestamp"]},"description":"List of tool invocations made during the chat"},"properties":{"type":"object","additionalProperties":{},"description":"Custom properties to include with the chat. These can be used for filtering and will show in the chat details page","example":{"source":"web","region":"US","sessionId":"abc123"}},"traceId":{"type":["string","null"],"description":"Optional OpenTelemetry trace ID for the chat. Surfaces the chat in the tracing tab.","example":"4bf92f3577b34da6a3ce929d0e0e4736"},"externalId":{"type":"string","maxLength":255,"description":"A stable identifier from your own system (e.g. session ID, conversation ID) used to correlate this chat with OpenTelemetry traces. Set the same value as a `roark.external_id` span or resource attribute on your traces and the matching trace will be linked automatically. Must be unique within a project."},"agent":{"allOf":[{"anyOf":[{"$ref":"#/components/schemas/ChatAgentIdentificationByRoarkId"},{"$ref":"#/components/schemas/ChatAgentIdentificationByName"},{"$ref":"#/components/schemas/ChatAgentIdentificationByCustomId"}]},{"type":"object","properties":{"prompt":{"type":"object","properties":{"resolvedPrompt":{"type":"string","description":"The agent's system prompt used during this chat"}},"required":["resolvedPrompt"],"description":"Agent's prompt configuration (optional)"}}}],"description":"Single agent participating in the chat. Use this for the simpler API when you have only one agent."},"agents":{"type":"array","items":{"allOf":[{"anyOf":[{"$ref":"#/components/schemas/ChatAgentIdentificationByRoarkId"},{"$ref":"#/components/schemas/ChatAgentIdentificationByName"},{"$ref":"#/components/schemas/ChatAgentIdentificationByCustomId"}]},{"type":"object","properties":{"prompt":{"type":"object","properties":{"resolvedPrompt":{"type":"string","description":"The agent's system prompt used during this chat"}},"required":["resolvedPrompt"],"description":"Agent's prompt configuration (optional)"}}}],"description":"Agent participating in the chat with their identification and prompt"},"description":"Agents participating in the chat. Each agent requires identification and prompt information."},"customer":{"type":"object","properties":{"label":{"type":["string","null"],"description":"Label to identify this customer in the chat (e.g., \"user-01\", \"anonymous-visitor\")"},"phoneNumberE164":{"type":["string","null"],"description":"Customer phone number in E.164 format (e.g., +14155551234), optional for chat customers"}},"required":["phoneNumberE164"],"description":"Single customer participating in the chat. Use this for the simpler API when you have only one customer."},"customers":{"type":"array","items":{"type":"object","properties":{"label":{"type":["string","null"],"description":"Label to identify this customer in the chat (e.g., \"user-01\", \"anonymous-visitor\")"},"phoneNumberE164":{"type":["string","null"],"description":"Customer phone number in E.164 format (e.g., +14155551234), optional for chat customers"}},"required":["phoneNumberE164"],"description":"Customer participating in the chat"},"description":"Customers participating in the chat."}},"required":["startTimestamp","endTimestamp","messages"],"description":"Chat creation payload. Supports singular (agent/customer) or plural (agents/customers) formats."},"ChatMessageAgent":{"type":"object","properties":{"role":{"type":"string","const":"AGENT","description":"The agent sent this message"},"text":{"type":"string","minLength":1,"description":"Message content"},"languageCode":{"type":"string","description":"ISO language code (e.g., \"en\")"},"startTimestamp":{"type":"string","description":"When the message was sent (ISO 8601). Must fall within the chat time range."},"endTimestamp":{"type":"string","description":"When the message finished sending (ISO 8601). For instant messages, can equal startTimestamp."},"agent":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"The Roark ID of the agent"},"customId":{"type":"string","description":"The custom ID set on the agent"}},"description":"Metadata about the agent that sent this message - used to match which agent from the agents array this message belongs to"}},"required":["role","text","startTimestamp"]},"ChatMessageCustomer":{"type":"object","properties":{"role":{"type":"string","const":"CUSTOMER","description":"The customer sent this message"},"text":{"type":"string","minLength":1,"description":"Message content"},"languageCode":{"type":"string","description":"ISO language code (e.g., \"en\")"},"startTimestamp":{"type":"string","description":"When the message was sent (ISO 8601). Must fall within the chat time range."},"endTimestamp":{"type":"string","description":"When the message finished sending (ISO 8601). For instant messages, can equal startTimestamp."},"customer":{"type":"object","properties":{"phoneNumberE164":{"type":"string","description":"Customer phone number in E.164 format"},"label":{"type":"string","description":"Customer label"}},"description":"Metadata about the customer that sent this message - used to match which customer from the customers array this message belongs to"}},"required":["role","text","startTimestamp"]},"ChatAgentIdentificationByRoarkId":{"type":"object","properties":{"roarkId":{"type":"string","format":"uuid","description":"Existing Roark agent ID"}},"required":["roarkId"]},"ChatAgentIdentificationByName":{"type":"object","properties":{"name":{"type":"string","description":"Agent name"},"description":{"type":"string","description":"Agent description"},"customId":{"type":"string","description":"Agent custom ID"}},"required":["name"],"description":"Find existing by customId if provided, otherwise reuse exact project name match before creating"},"ChatAgentIdentificationByCustomId":{"type":"object","properties":{"customId":{"type":"string","description":"Existing custom ID for a Roark agent"}},"required":["customId"]},"ListMetricDefinitionsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MetricDefinitionResponse"}},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["limit","hasMore","nextCursor"]}},"required":["data","pagination"],"description":"Cursor-paginated metric definitions available in the project"},"MetricDefinitionResponse":{"oneOf":[{"$ref":"#/components/schemas/LlmJudgeMetricResponse"},{"$ref":"#/components/schemas/ProviderMetricResponse"},{"$ref":"#/components/schemas/ThresholdMetricResponse"},{"$ref":"#/components/schemas/FormulaMetricResponse"},{"$ref":"#/components/schemas/PatternMetricResponse"}],"discriminator":{"propertyName":"calculationType","mapping":{"LLM_JUDGE":"#/components/schemas/LlmJudgeMetricResponse","PROVIDER":"#/components/schemas/ProviderMetricResponse","THRESHOLD":"#/components/schemas/ThresholdMetricResponse","FORMULA":"#/components/schemas/FormulaMetricResponse","PATTERN":"#/components/schemas/PatternMetricResponse"}},"description":"Metric definition data. The variant is selected by `calculationType`."},"LlmJudgeMetricResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug (e.g. \"call_reason\", \"customer_satisfaction\")"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"variantId":{"type":"string","format":"uuid","description":"The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config."},"versionId":{"type":"string","format":"uuid","description":"The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"description":"Which levels this metric can produce values at"},"supportedConversationSources":{"type":["array","null"],"items":{"type":"string","enum":["SIMULATED","LIVE"]},"description":"Which kinds of conversation this metric can be scored on. `null` means both. `[\"LIVE\"]` marks a metric that can only be scored from your own recording of a real call, and `[\"SIMULATED\"]` one that only applies to simulations."},"requiresLiveConversation":{"type":"boolean","description":"True when this metric can only be scored from a live recording (`supportedConversationSources` is `[\"LIVE\"]`). Selecting one of these on a simulation run forces live enrichment: the run waits for your recording and, if none arrives, the metric produces no value. Check this before a run rather than discovering the wait afterwards."},"supportsVariants":{"type":"boolean","description":"Whether you can create a variant of this metric with POST /v1/metric/definitions/{idOrSlug}/variants. False for threshold metrics (their configuration comes from the metric they derive from), for provider-computed metrics whose calculation lives in the collector rather than an editable prompt, and for metrics in a package that manages its own variants. Most of Roark’s own metrics are false, so read this rather than discovering it from a 403."},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"calculationType":{"type":"string","const":"LLM_JUDGE","description":"Metric evaluated by an LLM against a prompt."},"llmPrompt":{"type":["string","null"],"description":"The rubric this judge applies, as stored. Read it back to confirm which criteria are live after a create or update."},"booleanTrueLabel":{"type":["string","null"],"description":"For a BOOLEAN metric, what a `true` value means. Also given to the judge as its polarity rule."},"booleanFalseLabel":{"type":["string","null"],"description":"For a BOOLEAN metric, what a `false` value means. Also given to the judge as its polarity rule."}},"required":["id","slug","metricId","variantId","versionId","name","description","type","scope","supportedContexts","supportedConversationSources","requiresLiveConversation","supportsVariants","calculationType","llmPrompt","booleanTrueLabel","booleanFalseLabel"],"title":"LLM judge metric"},"ProviderMetricResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug (e.g. \"call_reason\", \"customer_satisfaction\")"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"variantId":{"type":"string","format":"uuid","description":"The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config."},"versionId":{"type":"string","format":"uuid","description":"The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"description":"Which levels this metric can produce values at"},"supportedConversationSources":{"type":["array","null"],"items":{"type":"string","enum":["SIMULATED","LIVE"]},"description":"Which kinds of conversation this metric can be scored on. `null` means both. `[\"LIVE\"]` marks a metric that can only be scored from your own recording of a real call, and `[\"SIMULATED\"]` one that only applies to simulations."},"requiresLiveConversation":{"type":"boolean","description":"True when this metric can only be scored from a live recording (`supportedConversationSources` is `[\"LIVE\"]`). Selecting one of these on a simulation run forces live enrichment: the run waits for your recording and, if none arrives, the metric produces no value. Check this before a run rather than discovering the wait afterwards."},"supportsVariants":{"type":"boolean","description":"Whether you can create a variant of this metric with POST /v1/metric/definitions/{idOrSlug}/variants. False for threshold metrics (their configuration comes from the metric they derive from), for provider-computed metrics whose calculation lives in the collector rather than an editable prompt, and for metrics in a package that manages its own variants. Most of Roark’s own metrics are false, so read this rather than discovering it from a 403."},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"calculationType":{"type":"string","const":"PROVIDER","description":"System-managed metric produced by an analysis provider."}},"required":["id","slug","metricId","variantId","versionId","name","description","type","scope","supportedContexts","supportedConversationSources","requiresLiveConversation","supportsVariants","calculationType"],"title":"Provider metric"},"ThresholdMetricResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug (e.g. \"call_reason\", \"customer_satisfaction\")"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"variantId":{"type":"string","format":"uuid","description":"The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config."},"versionId":{"type":"string","format":"uuid","description":"The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"description":"Which levels this metric can produce values at"},"supportedConversationSources":{"type":["array","null"],"items":{"type":"string","enum":["SIMULATED","LIVE"]},"description":"Which kinds of conversation this metric can be scored on. `null` means both. `[\"LIVE\"]` marks a metric that can only be scored from your own recording of a real call, and `[\"SIMULATED\"]` one that only applies to simulations."},"requiresLiveConversation":{"type":"boolean","description":"True when this metric can only be scored from a live recording (`supportedConversationSources` is `[\"LIVE\"]`). Selecting one of these on a simulation run forces live enrichment: the run waits for your recording and, if none arrives, the metric produces no value. Check this before a run rather than discovering the wait afterwards."},"supportsVariants":{"type":"boolean","description":"Whether you can create a variant of this metric with POST /v1/metric/definitions/{idOrSlug}/variants. False for threshold metrics (their configuration comes from the metric they derive from), for provider-computed metrics whose calculation lives in the collector rather than an editable prompt, and for metrics in a package that manages its own variants. Most of Roark’s own metrics are false, so read this rather than discovering it from a 403."},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"calculationType":{"type":"string","const":"THRESHOLD","description":"Boolean metric derived by comparing a source metric against a threshold."},"threshold":{"$ref":"#/components/schemas/ThresholdMetricDetails","description":"Threshold configuration."}},"required":["id","slug","metricId","variantId","versionId","name","description","type","scope","supportedContexts","supportedConversationSources","requiresLiveConversation","supportsVariants","calculationType"],"title":"Threshold metric"},"ThresholdMetricDetails":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"]},"thresholdValue":{"type":"string"},"aggregationMode":{"type":"string","enum":["EACH","COUNT","AVERAGE","MIN","MAX","MEDIAN","P95","P99","SUM"]},"countThreshold":{"type":["integer","null"]},"sourceParticipantRole":{"type":["string","null"],"enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"sourceVariantId":{"type":["string","null"],"format":"uuid"}},"required":["sourceMetricDefinitionId","operator","thresholdValue","aggregationMode","countThreshold","sourceParticipantRole","sourceVariantId"]},"FormulaMetricResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug (e.g. \"call_reason\", \"customer_satisfaction\")"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"variantId":{"type":"string","format":"uuid","description":"The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config."},"versionId":{"type":"string","format":"uuid","description":"The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"description":"Which levels this metric can produce values at"},"supportedConversationSources":{"type":["array","null"],"items":{"type":"string","enum":["SIMULATED","LIVE"]},"description":"Which kinds of conversation this metric can be scored on. `null` means both. `[\"LIVE\"]` marks a metric that can only be scored from your own recording of a real call, and `[\"SIMULATED\"]` one that only applies to simulations."},"requiresLiveConversation":{"type":"boolean","description":"True when this metric can only be scored from a live recording (`supportedConversationSources` is `[\"LIVE\"]`). Selecting one of these on a simulation run forces live enrichment: the run waits for your recording and, if none arrives, the metric produces no value. Check this before a run rather than discovering the wait afterwards."},"supportsVariants":{"type":"boolean","description":"Whether you can create a variant of this metric with POST /v1/metric/definitions/{idOrSlug}/variants. False for threshold metrics (their configuration comes from the metric they derive from), for provider-computed metrics whose calculation lives in the collector rather than an editable prompt, and for metrics in a package that manages its own variants. Most of Roark’s own metrics are false, so read this rather than discovering it from a 403."},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"calculationType":{"type":"string","const":"FORMULA","description":"Metric computed by evaluating an expression over other metrics."},"formula":{"$ref":"#/components/schemas/FormulaMetricDetails","description":"Formula configuration."}},"required":["id","slug","metricId","variantId","versionId","name","description","type","scope","supportedContexts","supportedConversationSources","requiresLiveConversation","supportsVariants","calculationType","formula"],"title":"Formula metric"},"FormulaMetricDetails":{"type":"object","properties":{"expression":{"type":"string"},"sources":{"type":"array","items":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"sourceVariantId":{"type":["string","null"],"format":"uuid"}},"required":["sourceMetricDefinitionId","sourceVariantId"]}}},"required":["expression","sources"]},"PatternMetricResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug (e.g. \"call_reason\", \"customer_satisfaction\")"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"variantId":{"type":"string","format":"uuid","description":"The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config."},"versionId":{"type":"string","format":"uuid","description":"The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"description":"Which levels this metric can produce values at"},"supportedConversationSources":{"type":["array","null"],"items":{"type":"string","enum":["SIMULATED","LIVE"]},"description":"Which kinds of conversation this metric can be scored on. `null` means both. `[\"LIVE\"]` marks a metric that can only be scored from your own recording of a real call, and `[\"SIMULATED\"]` one that only applies to simulations."},"requiresLiveConversation":{"type":"boolean","description":"True when this metric can only be scored from a live recording (`supportedConversationSources` is `[\"LIVE\"]`). Selecting one of these on a simulation run forces live enrichment: the run waits for your recording and, if none arrives, the metric produces no value. Check this before a run rather than discovering the wait afterwards."},"supportsVariants":{"type":"boolean","description":"Whether you can create a variant of this metric with POST /v1/metric/definitions/{idOrSlug}/variants. False for threshold metrics (their configuration comes from the metric they derive from), for provider-computed metrics whose calculation lives in the collector rather than an editable prompt, and for metrics in a package that manages its own variants. Most of Roark’s own metrics are false, so read this rather than discovering it from a 403."},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"calculationType":{"type":"string","const":"PATTERN","description":"Metric detecting a trigger condition followed by an outcome within a window."},"pattern":{"$ref":"#/components/schemas/PatternMetricDetails","description":"Pattern configuration."}},"required":["id","slug","metricId","variantId","versionId","name","description","type","scope","supportedContexts","supportedConversationSources","requiresLiveConversation","supportsVariants","calculationType","pattern"],"title":"Pattern metric"},"PatternMetricDetails":{"type":"object","properties":{"operation":{"type":"string","enum":["PATTERN_EXISTS","PATTERN_COUNT","OUTCOME_AGGREGATE"]},"windowMode":{"type":["string","null"]},"triggerCombinator":{"type":["string","null"],"enum":["AND","OR"]},"triggers":{"type":"array","items":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"]},"thresholdValue":{"type":"string"},"sourceParticipantRole":{"type":["string","null"],"enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"sourceVariantId":{"type":["string","null"],"format":"uuid"}},"required":["sourceMetricDefinitionId","operator","thresholdValue","sourceParticipantRole","sourceVariantId"]}},"outcome":{"type":["object","null"],"properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"]},"thresholdValue":{"type":"string"},"sourceParticipantRole":{"type":["string","null"],"enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"sourceVariantId":{"type":["string","null"],"format":"uuid"},"windowBefore":{"type":["integer","null"]},"windowAfter":{"type":["integer","null"]}},"required":["sourceMetricDefinitionId","operator","thresholdValue","sourceParticipantRole","sourceVariantId","windowBefore","windowAfter"]}},"required":["operation","windowMode","triggerCombinator","triggers","outcome"]},"CreateMetricDefinitionResponse":{"oneOf":[{"$ref":"#/components/schemas/LlmJudgeMetricResponse"},{"$ref":"#/components/schemas/FormulaMetricResponse"},{"$ref":"#/components/schemas/PatternMetricResponse"}],"discriminator":{"propertyName":"calculationType","mapping":{"LLM_JUDGE":"#/components/schemas/LlmJudgeMetricResponse","FORMULA":"#/components/schemas/FormulaMetricResponse","PATTERN":"#/components/schemas/PatternMetricResponse"}},"description":"The created metric definition. The variant is selected by `calculationType`."},"CreateMetricDefinitionInput":{"oneOf":[{"$ref":"#/components/schemas/PromptMetricInput"},{"$ref":"#/components/schemas/FormulaMetricInput"},{"$ref":"#/components/schemas/PatternMetricInput"}],"discriminator":{"propertyName":"calculationType","mapping":{"LLM_JUDGE":"#/components/schemas/PromptMetricInput","FORMULA":"#/components/schemas/FormulaMetricInput","PATTERN":"#/components/schemas/PatternMetricInput"}},"description":"Input for creating a new metric definition. `calculationType` selects the variant and defaults to LLM_JUDGE when omitted (legacy prompt-metric payloads remain valid). To create a threshold, use the threshold sub-resource."},"PromptMetricInput":{"type":"object","properties":{"calculationType":{"type":"string","const":"LLM_JUDGE","description":"LLM-evaluated metric."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Name of the metric","example":"Customer Satisfaction"},"slug":{"type":"string","minLength":1,"maxLength":50,"description":"Stable slug for the metric. Auto-generated from name if omitted.","example":"customer_satisfaction"},"metricId":{"type":"string","minLength":1,"maxLength":50,"description":"Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.","example":"customer_satisfaction"},"outputType":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces","example":"BOOLEAN"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"default":"GLOBAL","description":"Whether metric is global or per-participant (default: GLOBAL)"},"participantRole":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"],"description":"Participant role to evaluate. Required when scope is PER_PARTICIPANT."},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"minItems":1,"default":["CALL"],"description":"Which levels this metric can produce values at (default: [\"CALL\"])"},"llmPrompt":{"type":"string","maxLength":2000,"description":"LLM prompt/criteria for evaluating this metric. Required for BOOLEAN, NUMERIC, TEXT, and SCALE types.","example":"Evaluate whether the customer expressed satisfaction with the service provided."},"analysisPackageId":{"type":"string","format":"uuid","description":"ID of the analysis package to add this metric to. Optional: when omitted, the metric is added to a default \"Custom Metrics\" package for your project (created automatically the first time)."},"booleanTrueLabel":{"type":"string","description":"Label for the true case (only for BOOLEAN type)"},"booleanFalseLabel":{"type":"string","description":"Label for the false case (only for BOOLEAN type)"},"scaleMin":{"type":"integer","minimum":0,"maximum":100,"description":"Minimum value for scale. Required for SCALE type."},"scaleMax":{"type":"integer","minimum":0,"maximum":100,"description":"Maximum value for scale. Required for SCALE type."},"scaleLabels":{"type":"array","items":{"type":"object","properties":{"rangeMin":{"type":"number","description":"Minimum value for this label range"},"rangeMax":{"type":"number","description":"Maximum value for this label range"},"label":{"type":"string","description":"Label for this range"},"description":{"type":"string","description":"Description of what this range means"},"displayOrder":{"type":"integer","description":"Display order of this label"},"colorHex":{"type":"string","description":"Hex color code for this label (e.g. \"#FF0000\")"}},"required":["rangeMin","rangeMax","label","displayOrder"]},"description":"Labels for scale ranges (only for SCALE type)"},"classificationOptions":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"},"displayOrder":{"type":"integer"}},"required":["label","description","displayOrder"],"description":"Option for classification metrics."},"minItems":1,"description":"Options for classification. Required for CLASSIFICATION type."},"maxClassifications":{"type":"integer","minimum":1,"description":"Maximum number of classifications that can be selected (only for CLASSIFICATION type)"}},"required":["calculationType","name","outputType"],"title":"LLM judge metric"},"FormulaMetricInput":{"type":"object","properties":{"calculationType":{"type":"string","const":"FORMULA","description":"Metric computed by evaluating a mathematical expression over other metrics."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Name of the metric","example":"Customer Satisfaction"},"slug":{"type":"string","minLength":1,"maxLength":50,"description":"Stable slug for the metric. Auto-generated from name if omitted.","example":"customer_satisfaction"},"metricId":{"type":"string","minLength":1,"maxLength":50,"description":"Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.","example":"customer_satisfaction"},"outputType":{"type":"string","enum":["NUMERIC","BOOLEAN"],"description":"Output type of the formula. NUMERIC for arithmetic expressions, BOOLEAN for comparison expressions.","example":"NUMERIC"},"formula":{"type":"string","minLength":1,"maxLength":500,"description":"Formula expression using `{{id:<uuid>}}` references to source metrics. Operators depend on output type: +, -, *, / for NUMERIC; ==, !=, >=, <=, >, < for BOOLEAN.","example":"{{id:00000000-0000-0000-0000-000000000001}} / {{id:00000000-0000-0000-0000-000000000002}}"},"sources":{"type":"array","items":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid","description":"ID of a metric referenced in the formula"},"sourceVariantId":{"type":"string","format":"uuid","description":"Variant of the source metric to use"}},"required":["sourceMetricDefinitionId"]},"minItems":2,"description":"Source metrics referenced by the formula. Minimum 2."},"analysisPackageId":{"type":"string","format":"uuid","description":"ID of the analysis package to add this metric to. Optional: when omitted, the metric is added to a default \"Custom Metrics\" package for your project (created automatically the first time)."}},"required":["calculationType","name","outputType","formula","sources"],"title":"Formula metric"},"PatternMetricInput":{"type":"object","properties":{"calculationType":{"type":"string","const":"PATTERN","description":"Metric detecting temporal patterns: a trigger condition followed by an outcome within a window."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Name of the metric","example":"Customer Satisfaction"},"slug":{"type":"string","minLength":1,"maxLength":50,"description":"Stable slug for the metric. Auto-generated from name if omitted.","example":"customer_satisfaction"},"metricId":{"type":"string","minLength":1,"maxLength":50,"description":"Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.","example":"customer_satisfaction"},"operation":{"type":"string","enum":["PATTERN_EXISTS","PATTERN_COUNT","OUTCOME_AGGREGATE"],"description":"Pattern operation. PATTERN_EXISTS produces a BOOLEAN; PATTERN_COUNT produces a NUMERIC count; OUTCOME_AGGREGATE aggregates a numeric outcome.","example":"PATTERN_EXISTS"},"windowMode":{"type":"string","enum":["seconds","segments"],"default":"seconds","description":"Unit for trigger/outcome window values (default: seconds)"},"trigger":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"]},"thresholdValue":{"type":"string","minLength":1},"sourceParticipantRole":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"sourceVariantId":{"type":"string","format":"uuid"}},"required":["sourceMetricDefinitionId","operator","thresholdValue"],"description":"Single trigger condition. Use either trigger or triggers + triggerCombinator."},"triggers":{"type":"array","items":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"]},"thresholdValue":{"type":"string","minLength":1},"sourceParticipantRole":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"sourceVariantId":{"type":"string","format":"uuid"}},"required":["sourceMetricDefinitionId","operator","thresholdValue"]},"minItems":1,"description":"Multiple trigger conditions. Use with triggerCombinator."},"triggerCombinator":{"type":"string","enum":["AND","OR"],"description":"How to combine multiple triggers. Required when triggers has more than 1 entry."},"outcome":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"]},"thresholdValue":{"type":"string","minLength":1},"sourceParticipantRole":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"sourceVariantId":{"type":"string","format":"uuid"},"windowAfter":{"type":"integer","minimum":0,"description":"How far after the trigger to look for the outcome (in seconds or segments, see windowMode)"},"windowBefore":{"type":"integer","minimum":0,"description":"How far before the trigger to look for the outcome (default: 0)"}},"required":["sourceMetricDefinitionId","operator","thresholdValue","windowAfter"],"description":"Outcome condition evaluated within the window relative to the trigger."},"analysisPackageId":{"type":"string","format":"uuid","description":"ID of the analysis package to add this metric to. Optional: when omitted, the metric is added to a default \"Custom Metrics\" package for your project (created automatically the first time)."}},"required":["calculationType","name","operation","outcome"],"title":"Pattern metric"},"CreateThresholdInput":{"type":"object","properties":{"slug":{"type":"string","minLength":1,"maxLength":50,"description":"Stable slug for the metric. Auto-generated from name if omitted.","example":"customer_satisfaction"},"metricId":{"type":"string","minLength":1,"maxLength":50,"description":"Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.","example":"customer_satisfaction"},"operator":{"type":"string","enum":["GREATER_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN","LESS_THAN_OR_EQUALS","EQUALS","NOT_EQUALS"],"description":"Comparison operator","example":"GREATER_THAN_OR_EQUALS"},"value":{"type":"string","minLength":1,"description":"Value to compare the source metric against (as a string)","example":"4"},"aggregationMode":{"type":"string","enum":["EACH","COUNT","AVERAGE","MIN","MAX","MEDIAN","P95","P99","SUM"],"default":"EACH","description":"How to aggregate the source metric before applying the comparison (default: EACH)"},"countThreshold":{"type":"integer","minimum":0,"description":"Required when aggregationMode is COUNT. The threshold fires when the count is met."},"sourceParticipantRole":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"],"description":"When the source metric is per-participant, restrict evaluation to this role. Only valid for sources with TURN/SEGMENT contexts."},"sourceVariantId":{"type":"string","format":"uuid","description":"Variant of the source metric to use"}},"required":["operator","value"],"description":"Input for creating a new threshold derived from a source metric."},"UpdateMetricDefinitionResponse":{"oneOf":[{"$ref":"#/components/schemas/LlmJudgeMetricResponse"},{"$ref":"#/components/schemas/FormulaMetricResponse"},{"$ref":"#/components/schemas/PatternMetricResponse"},{"$ref":"#/components/schemas/ThresholdMetricResponse"}],"discriminator":{"propertyName":"calculationType","mapping":{"LLM_JUDGE":"#/components/schemas/LlmJudgeMetricResponse","FORMULA":"#/components/schemas/FormulaMetricResponse","PATTERN":"#/components/schemas/PatternMetricResponse","THRESHOLD":"#/components/schemas/ThresholdMetricResponse"}},"description":"The updated metric definition. The variant is selected by `calculationType`."},"UpdateMetricDefinitionInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"New name (only for metrics whose name is editable)"},"llmPrompt":{"type":"string","maxLength":2000,"description":"New LLM prompt (only for LLM_JUDGE metrics whose prompt is editable)"},"scaleMin":{"type":"integer","minimum":0,"maximum":100,"description":"New scale minimum (SCALE output only)"},"scaleMax":{"type":"integer","minimum":0,"maximum":100,"description":"New scale maximum (SCALE output only)"},"scaleLabels":{"type":"array","items":{"type":"object","properties":{"rangeMin":{"type":"number","description":"Minimum value for this label range"},"rangeMax":{"type":"number","description":"Maximum value for this label range"},"label":{"type":"string","description":"Label for this range"},"description":{"type":"string","description":"Description of what this range means"},"displayOrder":{"type":"integer","description":"Display order of this label"},"colorHex":{"type":"string","description":"Hex color code for this label (e.g. \"#FF0000\")"}},"required":["rangeMin","rangeMax","label","displayOrder"]},"description":"Replacement set of scale-range labels (SCALE output only)"},"booleanTrueLabel":{"type":"string","description":"New label for the true case (BOOLEAN output only)"},"booleanFalseLabel":{"type":"string","description":"New label for the false case (BOOLEAN output only)"},"classificationOptions":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"},"displayOrder":{"type":"integer"}},"required":["label","description","displayOrder"],"description":"Option for classification metrics."},"minItems":1,"description":"Replacement set of classification options (CLASSIFICATION output only)"},"maxClassifications":{"type":"integer","minimum":1,"description":"New maximum number of classifications (CLASSIFICATION output only)"},"toolDefinitionIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Replacement set of scoped tool-definition ids (only for metrics whose tool scoping is editable)"},"supportedContexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"minItems":1,"description":"Replacement set of supported contexts. Omit to leave unchanged."},"formula":{"type":"string","minLength":1,"maxLength":500,"description":"New formula expression (FORMULA only). Pass `sources` alongside if the referenced metrics change."},"sources":{"type":"array","items":{"type":"object","properties":{"sourceMetricDefinitionId":{"type":"string","format":"uuid","description":"ID of a metric referenced in the formula"},"sourceVariantId":{"type":"string","format":"uuid","description":"Variant of the source metric to use"}},"required":["sourceMetricDefinitionId"]},"description":"Replacement formula sources, required when `formula` changes the referenced metrics (FORMULA only)."},"changeReason":{"type":"string","description":"Optional free-text audit note recorded on the new version."},"slug":{},"metricId":{},"source":{},"organizationId":{},"projectId":{},"outputType":{},"scope":{},"participantRole":{},"calcType":{},"supportsMultipleVariants":{},"analysisPackageId":{}},"description":"Editable subset of a metric definition. Every update creates a new immutable version. Immutable fields (slug, scope, outputType, calcType, …) are rejected with a 400."},"MetricVariantListResponse":{"type":"array","items":{"$ref":"#/components/schemas/MetricVariantResponse"}},"MetricVariantResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the variant."},"metricDefinitionId":{"type":"string","format":"uuid","description":"The metric this variant configures."},"name":{"type":"string","description":"Name of the variant. \"Default\" is the one a metric is scored with unless something pins another."},"versionId":{"type":["string","null"],"format":"uuid","description":"The variant's current version: an immutable snapshot of its configuration. Editing the variant advances this. Null only for a variant left without one, which cannot be scored until it is configured."},"isSystem":{"type":"boolean","description":"True for Roark's own variant, shared by every organization. Editing one forks it for yours; the original is left alone."},"isDefault":{"type":"boolean","description":"Whether this is the variant a metric is scored with when nothing pins another."},"createdAt":{"type":"string","description":"When the variant was created."},"updatedAt":{"type":"string","description":"When the variant was last changed."}},"required":["id","metricDefinitionId","name","versionId","isSystem","isDefault","createdAt","updatedAt"],"description":"One named configuration of a metric."},"CreateMetricVariantInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Name for the new variant. Must be unique for this metric within your organization and cannot be `Default`.","example":"Strict"}},"required":["name"],"additionalProperties":false,"description":"Create a variant, seeded from the metric's Default configuration. Edit it afterwards with PUT to change what it measures.","example":{"name":"Strict"}},"UpdateMetricVariantInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Rename the variant. Does not change its configuration, so `versionId` is unaffected. `Default` is reserved."},"llmPrompt":{"type":"string","maxLength":2000,"description":"The rubric this variant applies. LLM judge metrics only."},"scaleMin":{"type":"integer","minimum":0,"maximum":100,"description":"Scale minimum. SCALE output only."},"scaleMax":{"type":"integer","minimum":0,"maximum":100,"description":"Scale maximum. SCALE output only."},"booleanTrueLabel":{"type":"string","maxLength":200,"description":"What a `true` value means. Given to the judge as its polarity rule, so keep it accurate."},"booleanFalseLabel":{"type":"string","maxLength":200,"description":"What a `false` value means. Given to the judge as its polarity rule, so keep it accurate."},"maxClassifications":{"type":"integer","minimum":1,"description":"Maximum classifications returned. CLASSIFICATION output only."},"changeReason":{"type":"string","maxLength":500,"description":"Free-text audit note recorded on the new version."}},"additionalProperties":false,"description":"Change a variant's name, its configuration, or both. Every configuration change creates a new immutable\nversion and advances `versionId`.\n\nEditing Roark's own variant forks it for your organization first: the response carries the new variant's id,\nand other organizations keep the original. Delete that variant to go back to Roark's version.","example":{"llmPrompt":"Did the agent verify identity before disclosing anything? {{transcript}}"}},"DeleteMetricVariantResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"]},"GetMetricPoliciesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MetricPolicyResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"],"description":"Paginated list of metric policies"},"MetricPolicyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the metric policy"},"name":{"type":"string","description":"Name of the metric policy"},"type":{"type":"string","enum":["SYSTEM","USER"],"description":"Type of the metric policy (SYSTEM or USER)"},"status":{"type":"string","enum":["ACTIVE","INACTIVE"],"description":"Status of the metric policy (ACTIVE or INACTIVE)"},"conditions":{"type":["array","null"],"items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"conditionType":{"type":"string","enum":["AGENT","CALL_SOURCE","CALL_PROPERTY","INTEGRATION"],"description":"Type of condition: AGENT (match by agent ID), CALL_SOURCE (match by source e.g. VAPI, RETELL), CALL_PROPERTY (match by call property key/value)"},"conditionKey":{"type":"string","description":"Key to match against. For AGENT: the agent ID. For CALL_SOURCE: the source name. For CALL_PROPERTY: the property key."},"conditionOperator":{"type":["string","null"],"enum":["EQUALS","NOT_EQUALS","CONTAINS","STARTS_WITH","GREATER_THAN","LESS_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN_OR_EQUALS"],"description":"Comparison operator. Required for CALL_PROPERTY conditions."},"conditionValue":{"type":["string","null"],"description":"Value to compare against. Required for CALL_PROPERTY conditions."}},"required":["conditionType","conditionKey","conditionOperator","conditionValue"]}}},"required":["conditions"]},"description":"Condition groups for this policy. Null means the policy matches all calls."},"metrics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Metric definitions associated with this policy"},"createdAt":{"type":"string","description":"When the policy was created"},"updatedAt":{"type":"string","description":"When the policy was last updated"}},"required":["id","name","type","status","conditions","metrics","createdAt","updatedAt"],"description":"A metric policy defining when metrics should be collected"},"CreateMetricPolicyInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name of the metric policy","example":"Evaluate all inbound calls"},"status":{"type":"string","enum":["ACTIVE","INACTIVE"],"default":"ACTIVE","description":"Status of the policy (default: ACTIVE)","example":"ACTIVE"},"modality":{"type":"string","enum":["call","chat"],"description":"Modality this policy targets. A policy fires for exactly one modality and can only reference metrics that support that modality.","example":"call"},"conditions":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"conditionType":{"type":"string","enum":["AGENT","CALL_SOURCE","CALL_PROPERTY","INTEGRATION"],"description":"Type of condition: AGENT (match by agent ID), CALL_SOURCE (match by source e.g. VAPI, RETELL), CALL_PROPERTY (match by call property key/value)"},"conditionKey":{"type":"string","description":"Key to match against. For AGENT: the agent ID. For CALL_SOURCE: the source name. For CALL_PROPERTY: the property key."},"conditionOperator":{"type":["string","null"],"enum":["EQUALS","NOT_EQUALS","CONTAINS","STARTS_WITH","GREATER_THAN","LESS_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN_OR_EQUALS"],"description":"Comparison operator. Required for CALL_PROPERTY conditions."},"conditionValue":{"type":["string","null"],"description":"Value to compare against. Required for CALL_PROPERTY conditions."}},"required":["conditionType","conditionKey"]}}},"required":["conditions"]},"description":"Condition groups. Omit to match all calls."},"metrics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Metric definitions to collect when this policy matches"}},"required":["name","modality","metrics"],"description":"Input for creating a new metric policy"},"UpdateMetricPolicyInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name of the metric policy"},"status":{"type":"string","enum":["ACTIVE","INACTIVE"],"description":"Status of the policy"},"conditions":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"conditionType":{"type":"string","enum":["AGENT","CALL_SOURCE","CALL_PROPERTY","INTEGRATION"],"description":"Type of condition: AGENT (match by agent ID), CALL_SOURCE (match by source e.g. VAPI, RETELL), CALL_PROPERTY (match by call property key/value)"},"conditionKey":{"type":"string","description":"Key to match against. For AGENT: the agent ID. For CALL_SOURCE: the source name. For CALL_PROPERTY: the property key."},"conditionOperator":{"type":["string","null"],"enum":["EQUALS","NOT_EQUALS","CONTAINS","STARTS_WITH","GREATER_THAN","LESS_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN_OR_EQUALS"],"description":"Comparison operator. Required for CALL_PROPERTY conditions."},"conditionValue":{"type":["string","null"],"description":"Value to compare against. Required for CALL_PROPERTY conditions."}},"required":["conditionType","conditionKey"]}}},"required":["conditions"]},"description":"Condition groups. Omit to keep existing, provide empty array to remove all conditions."},"metrics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Metric definitions to collect when this policy matches"}},"description":"Input for updating an existing metric policy"},"GetMetricCollectionJobsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MetricCollectionJobResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"],"description":"Paginated list of metric collection jobs"},"CreateMetricCollectionJobInput":{"type":"object","properties":{"callIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":500,"description":"Call IDs to collect metrics for. Mutually exclusive with chatIds. Max 500 per request."},"chatIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":500,"description":"Chat IDs to collect metrics for. Mutually exclusive with callIds. Max 500 per request."},"metrics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"maxItems":20,"description":"Metric definitions to collect. Max 20 per request."}},"required":["metrics"],"description":"Input for creating and running a metric collection job. Limits: ≤500 conversations, ≤20 metrics, ≤5000 total items per request."},"MetricCollectionJobMetricValuesResponse":{"type":"array","items":{"type":"object","properties":{"metricDefinitionId":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"values":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"}],"description":"The metric value (type depends on outputType). Present only on SUCCESS rows; omitted for NOT_APPLICABLE / DATA_MISSING / ERROR."},"callId":{"type":"string","format":"uuid","description":"ID of the call this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"chatId":{"type":"string","format":"uuid","description":"ID of the chat this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"captureStatus":{"type":"string","enum":["SUCCESS","NOT_APPLICABLE","DATA_MISSING","ERROR"],"description":"Result state of this metric computation. SUCCESS carries a real `value`; NOT_APPLICABLE / DATA_MISSING / ERROR do not (the `value` field is omitted). Non-SUCCESS rows only appear when the request includes ?status=all."},"errorMessage":{"type":"string","description":"Error detail when captureStatus is ERROR — e.g. provider down, LLM timeout. Undefined for other statuses."},"context":{"type":"string","enum":["CALL","SEGMENT","SEGMENT_RANGE"],"description":"Context level: CALL (entire conversation), SEGMENT (single segment), SEGMENT_RANGE (between/across segments)"},"participantRole":{"type":"string","enum":["agent","customer"],"description":"Role of participant (only for PER_PARTICIPANT metrics)"},"valueReasoning":{"type":"string","description":"Explanation for the metric value (especially useful for AI-computed metrics)"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence score (0-1) for the computed value. Defaults to 1.0 for deterministic metrics. Omitted on non-SUCCESS rows."},"computedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the metric was computed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that triggered this metric computation"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Segment information (for SEGMENT context metrics)"},"fromSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Starting segment information (for SEGMENT_RANGE context metrics)"},"toSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Ending segment information (for SEGMENT_RANGE context metrics)"}},"required":["captureStatus","context","computedAt"],"title":"Standard metric value","description":"A metric value entry. Applies to every metric."},{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"}],"description":"The metric value (type depends on outputType). Present only on SUCCESS rows; omitted for NOT_APPLICABLE / DATA_MISSING / ERROR."},"callId":{"type":"string","format":"uuid","description":"ID of the call this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"chatId":{"type":"string","format":"uuid","description":"ID of the chat this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"captureStatus":{"type":"string","enum":["SUCCESS","NOT_APPLICABLE","DATA_MISSING","ERROR"],"description":"Result state of this metric computation. SUCCESS carries a real `value`; NOT_APPLICABLE / DATA_MISSING / ERROR do not (the `value` field is omitted). Non-SUCCESS rows only appear when the request includes ?status=all."},"errorMessage":{"type":"string","description":"Error detail when captureStatus is ERROR — e.g. provider down, LLM timeout. Undefined for other statuses."},"context":{"type":"string","enum":["CALL","SEGMENT","SEGMENT_RANGE"],"description":"Context level: CALL (entire conversation), SEGMENT (single segment), SEGMENT_RANGE (between/across segments)"},"participantRole":{"type":"string","enum":["agent","customer"],"description":"Role of participant (only for PER_PARTICIPANT metrics)"},"valueReasoning":{"type":"string","description":"Explanation for the metric value (especially useful for AI-computed metrics)"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence score (0-1) for the computed value. Defaults to 1.0 for deterministic metrics. Omitted on non-SUCCESS rows."},"computedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the metric was computed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that triggered this metric computation"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Segment information (for SEGMENT context metrics)"},"fromSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Starting segment information (for SEGMENT_RANGE context metrics)"},"toSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Ending segment information (for SEGMENT_RANGE context metrics)"},"propertyVerdicts":{"type":"array","items":{"type":"object","properties":{"propertyName":{"type":"string","description":"The call property checked, as sent at ingest"},"expectedValue":{"type":"string","description":"The value supplied at ingest, frozen at scoring time"},"observedValue":{"type":"string","description":"What the transcript said instead. Only present when verdict is MISMATCH."},"verdict":{"type":"string","enum":["MATCH","MISMATCH","TRANSCRIPTION_ERROR","NOT_MENTIONED"],"description":"How this property resolved against the transcript. NOT_MENTIONED means the subject never came up and is not a mismatch."},"reasoning":{"type":"string","description":"Judge reasoning for this verdict"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"The transcript segment this property was referred to in: the conflicting value for MISMATCH, the confirming reference for MATCH. Omitted for NOT_MENTIONED and when the verdict could not be anchored."}},"required":["propertyName","expectedValue","verdict"]},"description":"Per-property verdicts for the Property Mismatch metric, in the order the properties were checked. Omitted for every other metric."}},"required":["captureStatus","context","computedAt"],"title":"Property verification metric value","description":"Returned for the Property Mismatch metric (`property_transcript_mismatch`): the standard entry plus the per-property verdict breakdown."}]},"description":"Array of metric values (multiple for PER_PARTICIPANT metrics, or multiple segments/turns)"}},"required":["metricDefinitionId","slug","metricId","name","description","type","scope","values"],"description":"Metric data grouped by metric definition"},"description":"Metric values produced by a specific metric collection job. Grouped by metric definition, same shape as the per-call metrics endpoint."},"RunSimulationResponse":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"The run. Poll it with GET /v1/simulation/plan/job/{jobId}."},"status":{"type":"string","enum":["PENDING","QUEUED","CREATING_SNAPSHOTS","CREATING_SIMULATIONS","PREPARING_CAPACITY","RUNNING_SIMULATIONS","COMPLETED","FAILED","TIMED_OUT","CANCELLED","CANCELLING","ENDING_SIMULATIONS"],"description":"Initial status. PENDING normally, or QUEUED when the plan runs sequentially and another job of its is still active."},"createdAt":{"type":"string","description":"When the run was created, ISO 8601."},"simulationRunPlanId":{"type":"string","format":"uuid","description":"The run plan behind this run, present whether or not it was saved. Pass it back as `planId` to run the same configuration again."},"savedAsPlan":{"type":"boolean","description":"Whether that plan is listed by GET /v1/simulation/plan. False for an unsaved run, whose plan is hidden."},"simulationJobCount":{"type":"integer","description":"How many simulated calls this run places."}},"required":["simulationRunPlanJobId","status","createdAt","simulationRunPlanId","savedAsPlan","simulationJobCount"],"description":"A started simulation run."},"RunSimulationInput":{"oneOf":[{"$ref":"#/components/schemas/RunSimulationFromConfig"},{"$ref":"#/components/schemas/RunSimulationFromPlanId"},{"$ref":"#/components/schemas/RunSimulationFromTemplate"}],"description":"A built-in template to run, a simulation to configure and run, or the id of a plan to run."},"RunSimulationFromConfig":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/InlineRunPlanConfig"},"saveAsPlan":{"type":"boolean","description":"Keeps this configuration as a run plan, listed by GET /v1/simulation/plan and re-runnable\nwith `planId`. Requires `plan.name`, since a plan you meant to keep should not be filed\nunder a generated one.\n\nOmitted or false gives a one-off. The run still needs a plan to execute, so one is created\neither way, but it is hidden: it carries this run and nothing else."},"variables":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"},"description":"Global format: key-value pairs that apply to ALL scenarios in the plan","example":{"orderNumber":"12345","environment":"staging"}},{"type":"array","items":{"type":"object","properties":{"flowId":{"type":"string","format":"uuid","description":"A customer flow this plan runs."},"happyPath":{"type":"boolean","const":true,"description":"Narrow to the flow's happy path."},"edgeCaseId":{"type":"string","format":"uuid","description":"Narrow to one edge case of that flow."},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"The values to apply."}},"required":["flowId","variables"]},"description":"Values scoped to the flows this plan runs","example":[{"flowId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","happyPath":true,"variables":{"orderNumber":"55555"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","edgeCaseId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]},{"type":"array","items":{"type":"object","properties":{"scenarioId":{"type":"string","format":"uuid","description":"ID of the scenario to apply variables to"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Key-value pairs for this scenario"}},"required":["scenarioId","variables"]},"deprecated":true,"description":"Deprecated, for plans built on scenarios. Plans built on customer flows target them with `flowId` instead.","example":[{"scenarioId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"scenarioId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]}],"description":"Values for the {{variables}} the run resolves, overriding whatever the plan has pinned.\n\nAn object applies them to the whole run:\n\n  { \"orderNumber\": \"12345\", \"tier\": \"gold\" }\n\nAn array applies them per flow, or to just its happy path or one of its edge cases, when a single\nset will not do. Each entry carries what it applies to:\n\n  [\n    { \"flowId\": \"550e8400-...\", \"variables\": { \"orderNumber\": \"12345\" } },\n    { \"flowId\": \"550e8400-...\", \"happyPath\": true, \"variables\": { \"orderNumber\": \"55555\" } },\n    { \"flowId\": \"550e8400-...\", \"edgeCaseId\": \"7a3d2e1f-...\", \"variables\": { \"orderNumber\": \"67890\" } }\n  ]\n\nAn entry that narrows to neither covers everything that flow resolves. A flow this plan does not\nattach, or an edge case that does not belong to the flow, is rejected rather than ignored.\n\nA plan built on scenarios rather than customer flows targets them the same way, with `scenarioId` in\nplace of `flowId`. That form is deprecated alongside scenarios themselves, and still accepted so runs\nagainst those plans keep working."}},"required":["plan"],"additionalProperties":false,"title":"New simulation","description":"Describe a simulation and run it, optionally keeping the configuration as a reusable plan.","example":{"saveAsPlan":true,"plan":{"name":"Billing regression","direction":"OUTBOUND","maxSimulationDurationSeconds":300,"agentEndpoints":[{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7"}],"metrics":[{"slug":"customer_satisfaction"}],"flows":[{"id":"550e8400-e29b-41d4-a716-446655440000","happyPath":true,"edgeCases":"ALL"}]},"variables":{"orderNumber":"12345"}}},"InlineRunPlanConfig":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"What to call this. Generated from the date when omitted, and required with `saveAsPlan`.","example":"Billing regression"},"description":{"type":"string","description":"Description of the run plan","example":"A run plan for testing inbound calls"},"direction":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the simulation (INBOUND or OUTBOUND)","example":"INBOUND"},"iterationCount":{"type":"integer","minimum":1,"maximum":10000,"default":1,"description":"Number of iterations to run for each test case (1-10000)","example":1},"maxConcurrentJobs":{"type":"integer","minimum":1,"default":5,"description":"Maximum number of concurrent simulation jobs","example":5},"maxSimulationDurationSeconds":{"type":"integer","minimum":1,"description":"Maximum duration in seconds for each simulation","example":300},"silenceTimeoutSeconds":{"type":"integer","minimum":1,"default":30,"description":"Timeout in seconds for silence detection","example":30},"endCallPhrases":{"type":"array","items":{"type":"string"},"default":["goodbye"],"description":"Phrases that trigger end of call. Empty array disables the feature.","example":["goodbye"]},"endCallReasons":{"type":"array","items":{"type":"string"},"default":[],"description":"Semantic conditions that trigger end of call. The LLM evaluates the conversation against these conditions. Empty array disables the feature.","example":["Order has been confirmed by the agent"]},"executionMode":{"type":"string","enum":["PARALLEL","SEQUENTIAL_SAME_RUN_PLAN","SEQUENTIAL_PROJECT"],"default":"PARALLEL","description":"Execution mode (PARALLEL or SEQUENTIAL)","example":"PARALLEL"},"scenarios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Scenario ID"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Template variables for this scenario instance. The same scenario can appear multiple times with different variables.","example":{"customerName":"John Doe","appointmentDate":"2024-02-15"}}},"required":["id"]},"minItems":1,"deprecated":true,"description":"Deprecated: use `flows` instead. Scenarios to include in this run plan. The same scenario ID can appear multiple times with different variables."},"flows":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanFlowSelection"},"minItems":1,"description":"Customer flows to include in this run plan. The same flow can appear more than once with a different persona override or different variables."},"personas":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Personas to include in this run plan. Required with `scenarios`; ignored with `flows`, where each variant carries its own persona."},"agentEndpoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Agent endpoints to include in this run plan"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanMetricRef"},"minItems":1,"description":"Metric definitions to include in this run plan. Reference each by `id` (UUID) or `slug`."},"includeFlowMetrics":{"type":"boolean","default":true,"description":"Also collect each attached flow's own metrics, on top of the `metrics` named here.\n\nDefault true, which is what you want when you brought your own flows and their graders.\nSet false for a run whose metric list is meant to be exhaustive: a template like Load\nTesting or Voicemail deliberately grades a narrow set, and inheriting every flow metric\non top multiplies analysis cost across the volume without adding signal.\n\nGET /v1/simulation/template returns the value each template expects.","example":true},"includeAutomaticMetrics":{"type":"boolean","default":true,"description":"Let the run add metrics by itself off the attached flows, on top of the `metrics` named here.\n\nTwo attach this way today: Agent Expectations wherever an attached flow has agent expectations\nwritten on it, and Keypad Entry wherever one has steps where the agent is expected to press keys.\nBoth grade something authored on the flow that nothing else measures, which is why it is on by\ndefault.\n\nSet false when the `metrics` list is meant to be exhaustive: a plan testing only whether the caller\ncan complete the flow may not want the agent graded on its expectations as well. False also pins\nthe plan against any automatic metric Roark adds later.","example":true},"enrichWithLiveConversation":{"type":"boolean","default":false,"description":"Merge the customer's own recording of the real call into each simulation, so metrics can be\nscored against the live leg as well as the simulated one. This is the API equivalent of the\ndashboard's live-enrichment toggle.\n\nWith this on, the run provisions a phone number and holds each call open for up to 15 minutes\nwaiting for a matching call to be posted to POST /v1/call. A call matches on the provisioned\nnumber (`roarkPhoneNumber` on the job) with a start time inside the simulation window. If\nnothing arrives, the simulation still completes and any `LIVE`-sourced metric produces no value.\n\nRequired by any metric whose `requiresLiveConversation` is true: without it that metric is\nsilently skipped.","example":false}},"required":["direction","maxSimulationDurationSeconds","agentEndpoints","metrics"],"additionalProperties":false,"description":"The simulation to run: what to call, who calls it, and what to measure."},"RunPlanFlowSelection":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The customer flow to run."},"slug":{"type":"string","minLength":1,"description":"The Roark-curated flow to run, by its stable slug. Use instead of `id` for a run you keep in version control: a curated flow’s id differs between deployments, its slug does not. Your own flows have no slug and are named by `id`.","example":"sf-prompt-injection"},"happyPath":{"type":"boolean","description":"Run the flow's happy path. Resolved when the run starts, so it follows the flow."},"edgeCases":{"anyOf":[{"type":"string","const":"ALL"},{"type":"array","items":{"$ref":"#/components/schemas/RunPlanEdgeCaseSelection"}}],"description":"`\"ALL\"` runs every edge case the flow has when the run starts, so one added later is covered.\nAn array runs only the ones you name, each able to carry its own persona override and values."},"personaOverrideId":{"type":["string","null"],"format":"uuid","description":"Runs everything this attachment resolves as that persona instead of its own."},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Values for everything it resolves.","example":{"customerName":"John Doe","appointmentDate":"2024-02-15"}}},"description":"One customer flow attached to a run plan, and which of its ways of running you cover.\n\nAttaching the same flow more than once with different overrides is how you fan it out across\npersonas or values.","example":{"id":"550e8400-e29b-41d4-a716-446655440000","happyPath":true,"edgeCases":[{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","variables":{"tier":"premium"}}]}},"RunPlanEdgeCaseSelection":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The edge case to run."},"slug":{"type":"string","minLength":1,"description":"The edge case to run, by its stable slug, matched within this flow. Use instead of `id` for a run you keep in version control: a curated edge case’s id differs between deployments and changes outright if it is renamed. Your own edge cases have no slug and are named by `id`.","example":"data-embedded-injection"},"personaOverrideId":{"type":["string","null"],"format":"uuid","description":"Run this one as that persona instead of its own."},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Values for this one only.","example":{"customerName":"John Doe","appointmentDate":"2024-02-15"}}}},"RunPlanMetricRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Metric definition UUID. Provide either this or `slug`, not both."},"slug":{"type":"string","minLength":1,"description":"Stable metric slug (e.g. `customer_satisfaction`). Provide either this or `id`, not both."},"metricId":{"type":"string","minLength":1,"description":"Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations."},"conversationSource":{"type":["string","null"],"enum":["SIMULATED","LIVE"],"description":"Which side of an enriched run this metric is scored on. Only meaningful with\n`enrichWithLiveConversation: true`, where a run has both a simulated conversation and the\ncustomer's own live recording of it.\n\nDefaults to `SIMULATED`. Use `LIVE` for a metric that must be measured against the real\nrecording (audio quality, provider latency) rather than the simulated leg. `null` means the\nsame as omitting it, so a plan read back from GET can be sent straight to PUT."}},"additionalProperties":false},"RunSimulationFromPlanId":{"type":"object","properties":{"planId":{"type":"string","format":"uuid","description":"The run plan to run, saved or hidden. Rename or unhide it with PUT /v1/simulation/plan/{planId}."},"variables":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"},"description":"Global format: key-value pairs that apply to ALL scenarios in the plan","example":{"orderNumber":"12345","environment":"staging"}},{"type":"array","items":{"type":"object","properties":{"flowId":{"type":"string","format":"uuid","description":"A customer flow this plan runs."},"happyPath":{"type":"boolean","const":true,"description":"Narrow to the flow's happy path."},"edgeCaseId":{"type":"string","format":"uuid","description":"Narrow to one edge case of that flow."},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"The values to apply."}},"required":["flowId","variables"]},"description":"Values scoped to the flows this plan runs","example":[{"flowId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","happyPath":true,"variables":{"orderNumber":"55555"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","edgeCaseId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]},{"type":"array","items":{"type":"object","properties":{"scenarioId":{"type":"string","format":"uuid","description":"ID of the scenario to apply variables to"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Key-value pairs for this scenario"}},"required":["scenarioId","variables"]},"deprecated":true,"description":"Deprecated, for plans built on scenarios. Plans built on customer flows target them with `flowId` instead.","example":[{"scenarioId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"scenarioId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]}],"description":"Values for the {{variables}} the run resolves, overriding whatever the plan has pinned.\n\nAn object applies them to the whole run:\n\n  { \"orderNumber\": \"12345\", \"tier\": \"gold\" }\n\nAn array applies them per flow, or to just its happy path or one of its edge cases, when a single\nset will not do. Each entry carries what it applies to:\n\n  [\n    { \"flowId\": \"550e8400-...\", \"variables\": { \"orderNumber\": \"12345\" } },\n    { \"flowId\": \"550e8400-...\", \"happyPath\": true, \"variables\": { \"orderNumber\": \"55555\" } },\n    { \"flowId\": \"550e8400-...\", \"edgeCaseId\": \"7a3d2e1f-...\", \"variables\": { \"orderNumber\": \"67890\" } }\n  ]\n\nAn entry that narrows to neither covers everything that flow resolves. A flow this plan does not\nattach, or an edge case that does not belong to the flow, is rejected rather than ignored.\n\nA plan built on scenarios rather than customer flows targets them the same way, with `scenarioId` in\nplace of `flowId`. That form is deprecated alongside scenarios themselves, and still accepted so runs\nagainst those plans keep working."}},"required":["planId"],"additionalProperties":false,"title":"Existing plan","description":"Run a plan that already exists.","example":{"planId":"3a1d5e7c-9b2f-4a6d-8c31-5f7e9d0a2b4c","variables":{"orderNumber":"99887"}}},"RunSimulationFromTemplate":{"type":"object","properties":{"template":{"type":"string","minLength":1,"description":"The template to run, as listed by GET /v1/simulation/template.","example":"health-check"},"agentEndpoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"The agent endpoints to call. No template can know these."},"direction":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the simulation (INBOUND or OUTBOUND)","example":"INBOUND"},"flows":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanFlowSelection"},"minItems":1,"description":"The flows to run, in the same shape a run plan takes them.\n\nRequired when the template lists no flows of its own: it presets what to measure, and this\nsays what to measure it on. Optional when it does, where these REPLACE the ones it would\nhave run, so you can narrow a suite to the cases you care about. Either way,\nGET /v1/simulation/template lists the flows and variant ids each template covers.","example":[{"slug":"sf-prompt-injection","edgeCases":[{"slug":"data-embedded-injection"}]},{"id":"3a1d5e7c-9b2f-4a6d-8c31-5f7e9d0a2b4c","happyPath":true}]},"name":{"type":"string","minLength":1,"description":"What to call this. Defaults to the template's name and the date, and required with `saveAsPlan`."},"saveAsPlan":{"type":"boolean","description":"Keeps the resolved configuration as a run plan, listed by GET /v1/simulation/plan and re-runnable with `planId`. Requires `name`."},"iterationCount":{"type":"integer","minimum":1,"maximum":10000,"default":1,"description":"Number of iterations to run for each test case (1-10000)","example":1},"maxConcurrentJobs":{"type":"integer","minimum":1,"default":5,"description":"Maximum number of concurrent simulation jobs","example":5},"maxSimulationDurationSeconds":{"type":"integer","minimum":1,"description":"Defaults to the template's `defaultMaxSimulationDurationSeconds`, as returned by GET /v1/simulation/template."},"silenceTimeoutSeconds":{"type":"integer","minimum":1,"default":30,"description":"Timeout in seconds for silence detection","example":30},"endCallPhrases":{"type":"array","items":{"type":"string"},"default":["goodbye"],"description":"Phrases that trigger end of call. Empty array disables the feature.","example":["goodbye"]},"endCallReasons":{"type":"array","items":{"type":"string"},"description":"Semantic conditions that trigger end of call. The LLM evaluates the conversation against these conditions. Defaults to the template's `defaultEndCallReasons`, as returned by GET /v1/simulation/template. Pass an empty array to run with none.","example":["Order has been confirmed by the agent"]},"executionMode":{"type":"string","enum":["PARALLEL","SEQUENTIAL_SAME_RUN_PLAN","SEQUENTIAL_PROJECT"],"default":"PARALLEL","description":"Execution mode (PARALLEL or SEQUENTIAL)","example":"PARALLEL"},"enrichWithLiveConversation":{"type":"boolean","default":false,"description":"Merge the customer's own recording of the real call into each simulation, so metrics can be\nscored against the live leg as well as the simulated one. This is the API equivalent of the\ndashboard's live-enrichment toggle.\n\nWith this on, the run provisions a phone number and holds each call open for up to 15 minutes\nwaiting for a matching call to be posted to POST /v1/call. A call matches on the provisioned\nnumber (`roarkPhoneNumber` on the job) with a start time inside the simulation window. If\nnothing arrives, the simulation still completes and any `LIVE`-sourced metric produces no value.\n\nRequired by any metric whose `requiresLiveConversation` is true: without it that metric is\nsilently skipped.","example":false},"variables":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"},"description":"Global format: key-value pairs that apply to ALL scenarios in the plan","example":{"orderNumber":"12345","environment":"staging"}},{"type":"array","items":{"type":"object","properties":{"flowId":{"type":"string","format":"uuid","description":"A customer flow this plan runs."},"happyPath":{"type":"boolean","const":true,"description":"Narrow to the flow's happy path."},"edgeCaseId":{"type":"string","format":"uuid","description":"Narrow to one edge case of that flow."},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"The values to apply."}},"required":["flowId","variables"]},"description":"Values scoped to the flows this plan runs","example":[{"flowId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","happyPath":true,"variables":{"orderNumber":"55555"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","edgeCaseId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]}],"description":"Values for the {{variables}} the run resolves. An object applies them everywhere; an array\ntargets a flow, its happy path, or one of its edge cases with `flowId`.\n\nThe scenario-scoped form the other variants accept is not valid here: a template run is\nalways flow-based, so there would be no scenario for it to reach."}},"required":["template","agentEndpoints","direction"],"additionalProperties":false,"title":"From template","description":"Run one of the built-in templates against your agent.","example":{"template":"health-check","direction":"OUTBOUND","agentEndpoints":[{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7"}]}},"GetEnvironmentsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"],"description":"Paginated list of environments: the project's own plus the shared Roark-curated ones"},"EnvironmentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1},"description":{"type":["string","null"]},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE"},"backgroundNoiseVolume":{"type":"number","minimum":0,"maximum":1,"default":0.1},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","backgroundNoise","backgroundNoiseVolume","createdAt","updatedAt"],"description":"A simulation environment: the ambient conditions a customer flow variant runs under. The list includes both your own and the ones Roark curates for every project."},"CreateEnvironmentInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Display name, shown wherever a flow variant references the environment","example":"Busy call centre"},"description":{"type":["string","null"],"description":"Optional note on when to use this environment","example":"Open-plan office at peak hours"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"description":"The noise bed played underneath the simulated caller. NONE plays nothing.","example":"OFFICE"},"backgroundNoiseVolume":{"type":"number","minimum":0,"maximum":1,"default":0.1,"description":"How loud the bed plays, as a gain from 0 (silent) to 1 (as loud as the caller). Defaults to 0.1, which sits well under the caller. Ignored on Vapi endpoints, which have no level control.","example":0.3}},"required":["name","backgroundNoise"],"description":"Input for creating an environment"},"UpdateEnvironmentInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Display name, shown wherever a flow variant references the environment","example":"Busy call centre"},"description":{"type":["string","null"],"description":"Optional note on when to use this environment","example":"Open-plan office at peak hours"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"description":"The noise bed played underneath the simulated caller. NONE plays nothing.","example":"OFFICE"},"backgroundNoiseVolume":{"type":"number","minimum":0,"maximum":1,"default":0.1,"description":"How loud the bed plays, as a gain from 0 (silent) to 1 (as loud as the caller). Defaults to 0.1, which sits well under the caller. Ignored on Vapi endpoints, which have no level control.","example":0.3}},"description":"Input for updating an environment. Only the fields sent are changed. Roark-curated environments cannot be edited."},"DeleteEnvironmentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the deleted environment"},"deleted":{"type":"boolean","const":true,"description":"Always true when the environment was deleted"}},"required":["id","deleted"]},"GetRunPlansResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"],"description":"Paginated list of simulation run plans"},"RunPlanResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the run plan"},"name":{"type":"string","description":"Name of the run plan"},"isConfigManaged":{"type":"boolean","description":"Whether this plan is managed by config as code. A managed plan is reconciled from your config: PUT and DELETE on it return 409, and changes belong in the config file."},"description":{"type":["string","null"],"description":"Description of the run plan"},"direction":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the simulation (INBOUND or OUTBOUND)"},"iterationCount":{"type":"integer","description":"Number of iterations to run for each test case"},"maxConcurrentJobs":{"type":"integer","description":"Maximum number of concurrent simulation jobs"},"maxSimulationDurationSeconds":{"type":"integer","description":"Maximum duration in seconds for each simulation"},"silenceTimeoutSeconds":{"type":"integer","description":"Timeout in seconds for silence detection"},"endCallPhrases":{"type":"array","items":{"type":"string"},"description":"Phrases that trigger end of call. Empty array means disabled."},"endCallReasons":{"type":"array","items":{"type":"string"},"description":"Semantic conditions that trigger end of call. The LLM evaluates the conversation against these conditions. Empty array means disabled."},"executionMode":{"type":"string","enum":["PARALLEL","SEQUENTIAL_SAME_RUN_PLAN","SEQUENTIAL_PROJECT"],"description":"Execution mode (PARALLEL or SEQUENTIAL)"},"scenarios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Template variables for this scenario instance. Absent when no variables are set. The same scenario can appear multiple times with different variables.","example":{"customerName":"John Doe","appointmentDate":"2024-02-15"}}},"required":["id"]},"deprecated":true,"description":"Deprecated: use `flows` instead. Scenarios included in this run plan."},"flows":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanFlowSelection"},"description":"Customer flows included in this run plan"},"personas":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Personas included in this run plan. Only meaningful alongside `scenarios`."},"agentEndpoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Agent endpoints included in this run plan"},"evaluators":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Deprecated: Use metrics instead. Evaluators included in this run plan."},"metrics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"conversationSource":{"type":["string","null"],"enum":["SIMULATED","LIVE"],"description":"Which side of an enriched run this metric is scored on. `null` means the default, SIMULATED."}},"required":["id","conversationSource"]},"description":"Metric definitions included in this run plan"},"enrichWithLiveConversation":{"type":"boolean","description":"Whether this plan merges the customer's own live recording into each simulation."},"includeFlowMetrics":{"type":"boolean","description":"Whether this plan also collects each attached flow's own metrics, on top of its own list."},"includeAutomaticMetrics":{"type":"boolean","description":"Whether this plan lets a run add metrics by itself off the attached flows, on top of its own list. False means the `metrics` list is the whole answer."},"testCaseCount":{"type":"integer","description":"Total number of test cases generated from the plan configuration"},"createdAt":{"type":"string","description":"When the run plan was created"},"updatedAt":{"type":"string","description":"When the run plan was last updated"}},"required":["id","name","isConfigManaged","direction","iterationCount","maxConcurrentJobs","maxSimulationDurationSeconds","silenceTimeoutSeconds","endCallPhrases","endCallReasons","executionMode","scenarios","flows","personas","agentEndpoints","evaluators","metrics","enrichWithLiveConversation","includeFlowMetrics","includeAutomaticMetrics","testCaseCount","createdAt","updatedAt"],"description":"A simulation run plan defining the test matrix"},"CreateRunPlanResponse":{"type":"object","properties":{"runPlan":{"$ref":"#/components/schemas/RunPlanResponse"},"runPlanJob":{"oneOf":[{"$ref":"#/components/schemas/RunSimulationPlanResponse"},{"type":"null"}],"description":"The triggered job, only present if autoRun was true"}},"required":["runPlan"],"description":"Response when creating a run plan, optionally including a triggered job"},"RunSimulationPlanResponse":{"type":"object","properties":{"simulationRunPlanId":{"type":"string","format":"uuid","description":"ID of the simulation run plan that was executed"},"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"ID of the simulation run plan job that was created"},"status":{"type":"string","enum":["PENDING","QUEUED","CREATING_SNAPSHOTS","CREATING_SIMULATIONS","PREPARING_CAPACITY","RUNNING_SIMULATIONS","COMPLETED","FAILED","TIMED_OUT","CANCELLED","CANCELLING","ENDING_SIMULATIONS"],"description":"Initial status of the job"},"createdAt":{"type":"string","description":"When the job was created"}},"required":["simulationRunPlanId","simulationRunPlanJobId","status","createdAt"],"description":"Response when triggering a simulation run plan","example":{"simulationRunPlanId":"9a8b7c6d-5e4f-3210-abcd-ef9876543210","simulationRunPlanJobId":"7f3e4d2c-8a91-4b5c-9e6f-1a2b3c4d5e6f","status":"PENDING","createdAt":"2024-01-15T10:30:00Z"}},"CreateRunPlanInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name of the run plan","example":"My Run Plan"},"description":{"type":"string","description":"Description of the run plan","example":"A run plan for testing inbound calls"},"direction":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the simulation (INBOUND or OUTBOUND)","example":"INBOUND"},"iterationCount":{"type":"integer","minimum":1,"maximum":10000,"default":1,"description":"Number of iterations to run for each test case (1-10000)","example":1},"maxConcurrentJobs":{"type":"integer","minimum":1,"default":5,"description":"Maximum number of concurrent simulation jobs","example":5},"maxSimulationDurationSeconds":{"type":"integer","minimum":1,"description":"Maximum duration in seconds for each simulation","example":300},"silenceTimeoutSeconds":{"type":"integer","minimum":1,"default":30,"description":"Timeout in seconds for silence detection","example":30},"endCallPhrases":{"type":"array","items":{"type":"string"},"default":["goodbye"],"description":"Phrases that trigger end of call. Empty array disables the feature.","example":["goodbye"]},"endCallReasons":{"type":"array","items":{"type":"string"},"default":[],"description":"Semantic conditions that trigger end of call. The LLM evaluates the conversation against these conditions. Empty array disables the feature.","example":["Order has been confirmed by the agent"]},"executionMode":{"type":"string","enum":["PARALLEL","SEQUENTIAL_SAME_RUN_PLAN","SEQUENTIAL_PROJECT"],"default":"PARALLEL","description":"Execution mode (PARALLEL or SEQUENTIAL)","example":"PARALLEL"},"scenarios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Scenario ID"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Template variables for this scenario instance. The same scenario can appear multiple times with different variables.","example":{"customerName":"John Doe","appointmentDate":"2024-02-15"}}},"required":["id"]},"minItems":1,"deprecated":true,"description":"Deprecated: use `flows` instead. Scenarios to include in this run plan. The same scenario ID can appear multiple times with different variables."},"flows":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanFlowSelection"},"minItems":1,"description":"Customer flows to include in this run plan. The same flow can appear more than once with a different persona override or different variables."},"personas":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Personas to include in this run plan. Required with `scenarios`; ignored with `flows`, where each variant carries its own persona."},"agentEndpoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Agent endpoints to include in this run plan"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanMetricRef"},"minItems":1,"description":"Metric definitions to include in this run plan. Reference each by `id` (UUID) or `slug`."},"includeFlowMetrics":{"type":"boolean","default":true,"description":"Also collect each attached flow's own metrics, on top of the `metrics` named here.\n\nDefault true, which is what you want when you brought your own flows and their graders.\nSet false for a run whose metric list is meant to be exhaustive: a template like Load\nTesting or Voicemail deliberately grades a narrow set, and inheriting every flow metric\non top multiplies analysis cost across the volume without adding signal.\n\nGET /v1/simulation/template returns the value each template expects.","example":true},"includeAutomaticMetrics":{"type":"boolean","default":true,"description":"Let the run add metrics by itself off the attached flows, on top of the `metrics` named here.\n\nTwo attach this way today: Agent Expectations wherever an attached flow has agent expectations\nwritten on it, and Keypad Entry wherever one has steps where the agent is expected to press keys.\nBoth grade something authored on the flow that nothing else measures, which is why it is on by\ndefault.\n\nSet false when the `metrics` list is meant to be exhaustive: a plan testing only whether the caller\ncan complete the flow may not want the agent graded on its expectations as well. False also pins\nthe plan against any automatic metric Roark adds later.","example":true},"enrichWithLiveConversation":{"type":"boolean","default":false,"description":"Merge the customer's own recording of the real call into each simulation, so metrics can be\nscored against the live leg as well as the simulated one. This is the API equivalent of the\ndashboard's live-enrichment toggle.\n\nWith this on, the run provisions a phone number and holds each call open for up to 15 minutes\nwaiting for a matching call to be posted to POST /v1/call. A call matches on the provisioned\nnumber (`roarkPhoneNumber` on the job) with a start time inside the simulation window. If\nnothing arrives, the simulation still completes and any `LIVE`-sourced metric produces no value.\n\nRequired by any metric whose `requiresLiveConversation` is true: without it that metric is\nsilently skipped.","example":false},"autoRun":{"type":"boolean","default":false,"deprecated":true,"description":"Deprecated: use POST /v1/simulation/run, which starts a run and accepts runtime `variables` as well. This flag runs the plan with only the values pinned on it.","example":false}},"required":["name","direction","maxSimulationDurationSeconds","agentEndpoints","metrics"],"additionalProperties":false,"description":"Input for creating a new simulation run plan"},"UpdateRunPlanInput":{"type":"object","properties":{"isHidden":{"type":"boolean","description":"Whether this plan is hidden from GET /v1/simulation/plan.\n\nA run started without `saveAsPlan` creates a hidden plan to carry it. Send\n`{ \"name\": \"...\", \"isHidden\": false }` to keep that configuration as a reusable plan,\nwhich is what the app does when you save a one-off run."},"name":{"type":"string","minLength":1,"description":"Name of the run plan"},"description":{"type":"string","description":"Description of the run plan"},"direction":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the simulation (INBOUND or OUTBOUND)"},"iterationCount":{"type":"integer","minimum":1,"maximum":10000,"description":"Number of iterations to run for each test case (1-10000)"},"maxConcurrentJobs":{"type":"integer","minimum":1,"description":"Maximum number of concurrent simulation jobs"},"maxSimulationDurationSeconds":{"type":"integer","minimum":1,"description":"Maximum duration in seconds for each simulation"},"silenceTimeoutSeconds":{"type":"integer","minimum":1,"description":"Timeout in seconds for silence detection"},"endCallPhrases":{"type":"array","items":{"type":"string"},"description":"Phrases that trigger end of call. Empty array disables the feature."},"endCallReasons":{"type":"array","items":{"type":"string"},"description":"Semantic conditions that trigger end of call. The LLM evaluates the conversation against these conditions. Empty array disables the feature."},"executionMode":{"type":"string","enum":["PARALLEL","SEQUENTIAL_SAME_RUN_PLAN","SEQUENTIAL_PROJECT"],"description":"Execution mode (PARALLEL or SEQUENTIAL)"},"scenarios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Scenario ID"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Template variables for this scenario instance. The same scenario can appear multiple times with different variables.","example":{"customerName":"John Doe","appointmentDate":"2024-02-15"}}},"required":["id"]},"deprecated":true,"description":"Deprecated: use `flows` instead. Replaces the scenarios on this run plan. Omit to leave them unchanged; send an empty array to detach them all, which is how a scenario-based plan is moved over to flows."},"flows":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanFlowSelection"},"description":"Replaces the customer flows attached to this run plan. Omit to leave them unchanged; send an empty array to detach them all."},"personas":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Personas to include in this run plan"},"agentEndpoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"minItems":1,"description":"Agent endpoints to include in this run plan"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/RunPlanMetricRef"},"minItems":1,"description":"Metric definitions to include in this run plan. Reference each by `id` (UUID) or `slug`."},"enrichWithLiveConversation":{"type":"boolean","description":"Whether to merge the customer's own live recording into each simulation of this plan."},"includeFlowMetrics":{"type":"boolean","description":"Whether to also collect each attached flow's own metrics, on top of this plan's list."},"includeAutomaticMetrics":{"type":"boolean","description":"Whether to let the run add metrics by itself off the attached flows. See `POST /v1/simulation/plan`."}},"additionalProperties":false,"description":"Input for updating an existing simulation run plan"},"GetSimulationPlanJobsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"ID of the simulation run plan job"},"simulationRunPlanId":{"type":"string","format":"uuid","description":"ID of the simulation run plan"},"status":{"type":"string","enum":["PENDING","QUEUED","CREATING_SNAPSHOTS","CREATING_SIMULATIONS","PREPARING_CAPACITY","RUNNING_SIMULATIONS","COMPLETED","FAILED","TIMED_OUT","CANCELLED","CANCELLING","ENDING_SIMULATIONS"],"description":"Job status"},"triggeredBy":{"type":"string","enum":["SCHEDULED","USER_TRIGGERED_FROM_UI","RE_RUN","TRIGGERED_FROM_API","SYSTEM"],"description":"How the job was triggered (SCHEDULED, USER_TRIGGERED_FROM_UI, TRIGGERED_FROM_API, RE_RUN, or SYSTEM). SYSTEM is used when the job was started by an internal admin acting on behalf of the project (the original user identity is not exposed)."},"createdAt":{"type":"string","description":"When the job was created"},"startedAt":{"type":["string","null"],"description":"When the job started"},"endedAt":{"type":["string","null"],"description":"When the job ended"}},"required":["simulationRunPlanJobId","simulationRunPlanId","status","triggeredBy","createdAt"]}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of matching plan jobs"},"hasMore":{"type":"boolean","description":"Whether there are more results available"},"nextCursor":{"type":["string","null"],"description":"Cursor to use for fetching the next page"}},"required":["total","hasMore"]}},"required":["data","pagination"],"description":"Paginated list of simulation run plan jobs"},"GetSimulationPlanJobResponse":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"ID of the simulation run plan job"},"simulationRunPlanId":{"type":"string","format":"uuid","description":"ID of the simulation run plan"},"status":{"type":"string","enum":["PENDING","QUEUED","CREATING_SNAPSHOTS","CREATING_SIMULATIONS","PREPARING_CAPACITY","RUNNING_SIMULATIONS","COMPLETED","FAILED","TIMED_OUT","CANCELLED","CANCELLING","ENDING_SIMULATIONS"],"description":"Job status"},"createdAt":{"type":"string","description":"When the job was created"},"startedAt":{"type":["string","null"],"description":"When the job started"},"endedAt":{"type":["string","null"],"description":"When the job ended"},"simulationJobs":{"type":"array","items":{"type":"object","properties":{"simulationJobId":{"type":"string","format":"uuid","description":"Simulation job ID"},"status":{"type":"string","enum":["PENDING","QUEUED","PROCESSING","COMPLETED","FAILED","TIMED_OUT","CANCELLED","CANCELLING"],"description":"Job status"},"processingStatus":{"type":"string","enum":["PENDING","CONNECTING","WAITING_FOR_OUTBOUND_CALL","SIMULATING","ENDING","ANALYZING","WAITING_FOR_LIVE_CONVERSATION","EVALUATING","COLLECTING_METRICS","COMPLETED"],"description":"Processing status. PENDING until the job starts connecting."},"callId":{"type":["string","null"],"format":"uuid","description":"ID of the call created for this simulation job. Null if the call has not been created yet."},"roarkPhoneNumber":{"type":["string","null"],"description":"Phone number provisioned by Roark for this simulation job in E.164 format. Null if the simulation job is queued and has not been assigned a phone number yet."},"persona":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"]},"scenario":{"$ref":"#/components/schemas/ScenarioResponse"},"agentEndpoint":{"$ref":"#/components/schemas/AgentEndpointResponse"},"invalidation":{"oneOf":[{"$ref":"#/components/schemas/SimulationJobInvalidation"},{"type":"null"}],"description":"Present when the result does not count (a strict flow went off script and its policy invalidated the run); null otherwise."},"createdAt":{"type":"string","description":"When the simulation job was created"},"startedAt":{"type":["string","null"],"description":"When the simulation job started"},"completedAt":{"type":["string","null"],"description":"When the simulation job completed"}},"required":["simulationJobId","status","processingStatus","persona","scenario","agentEndpoint","invalidation","createdAt"]},"description":"List of simulation jobs (calls) in this run plan job"}},"required":["simulationRunPlanJobId","simulationRunPlanId","status","createdAt","simulationJobs"],"description":"Simulation run plan job with all associated simulation jobs","example":{"simulationRunPlanJobId":"7f3e4d2c-8a91-4b5c-9e6f-1a2b3c4d5e6f","simulationRunPlanId":"9a8b7c6d-5e4f-3210-abcd-ef9876543210","status":"RUNNING_SIMULATIONS","createdAt":"2024-01-15T10:30:00Z","startedAt":"2024-01-15T10:30:15Z","endedAt":null,"simulationJobs":[{"simulationJobId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","status":"COMPLETED","processingStatus":"COMPLETED","callId":"b2c3d4e5-f6a7-8901-bcde-f23456789012","roarkPhoneNumber":"+15551234567","invalidation":null,"persona":{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"Sarah Johnson - Anxious Patient","displayName":"Anxious Patient","language":"EN","secondaryLanguage":null,"understoodLanguages":["EN"],"accent":"US","age":"ADULT","gender":"FEMALE","backgroundNoise":"OFFICE","speechPace":"NORMAL","speechClarity":"CLEAR","hasDisfluencies":false,"baseEmotion":"FRUSTRATED","intentClarity":"CLEAR","confirmationStyle":"EXPLICIT","memoryReliability":"HIGH","responseTiming":"NORMAL","backstoryPrompt":"A busy professional calling during lunch break","idleMessages":null,"idleTimeoutSeconds":10,"idleMessageMaxSpokenCount":3,"idleMessageResetCountOnUserSpeechEnabled":true,"properties":{"age":"35","zipCode":"94105"},"createdAt":"2025-01-10T12:00:00.000Z","updatedAt":"2025-01-10T12:00:00.000Z"},"scenario":{"id":"f8e7d6c5-b4a3-9281-7069-5f4e3d2c1b0a","description":"Patient calling to schedule an urgent dental appointment"},"agentEndpoint":{"id":"3c2b1a09-8f7e-6d5c-4b3a-291807060504","name":"PHONE","phoneNumber":"+15555551234","type":"PHONE"},"createdAt":"2024-01-15T10:30:20Z","startedAt":"2024-01-15T10:30:25Z","completedAt":"2024-01-15T10:32:45Z"}]}},"ScenarioResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Scenario ID"},"description":{"type":["string","null"],"description":"Scenario description"}},"required":["id"],"description":"Scenario used in a simulation"},"AgentEndpointResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Agent endpoint ID"},"name":{"type":"string","description":"Agent endpoint name"},"phoneNumber":{"type":["string","null"],"description":"Agent endpoint phone number"},"type":{"type":"string","enum":["PHONE","WEBSOCKET","LIVEKIT","SMALL_WEBRTC","ELEVENLABS_WS","KORE","GOOGLE_CES","DAILY"],"description":"Agent endpoint type"}},"required":["id","name","phoneNumber","type"],"description":"Agent endpoint used in a simulation"},"SimulationJobInvalidation":{"type":"object","properties":{"reason":{"type":"string","enum":["SCRIPT_DIVERGED"],"description":"Why the result does not count. `SCRIPT_DIVERGED`: a strict flow went off script at a step whose off-script policy is HANG_UP_INVALIDATE."},"detail":{"type":["string","null"],"description":"One sentence: where the script was left and what your agent did instead."},"invalidatedAt":{"type":"string","description":"When the run was invalidated."}},"required":["reason","invalidatedAt"],"description":"Present when the run was invalidated: it keeps its transcript and recording, but nothing scored it and it is excluded from every run total."},"RunSimulationPlanBody":{"type":"object","properties":{"variables":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"},"description":"Global format: key-value pairs that apply to ALL scenarios in the plan","example":{"orderNumber":"12345","environment":"staging"}},{"type":"array","items":{"type":"object","properties":{"flowId":{"type":"string","format":"uuid","description":"A customer flow this plan runs."},"happyPath":{"type":"boolean","const":true,"description":"Narrow to the flow's happy path."},"edgeCaseId":{"type":"string","format":"uuid","description":"Narrow to one edge case of that flow."},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"The values to apply."}},"required":["flowId","variables"]},"description":"Values scoped to the flows this plan runs","example":[{"flowId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","happyPath":true,"variables":{"orderNumber":"55555"}},{"flowId":"550e8400-e29b-41d4-a716-446655440000","edgeCaseId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]},{"type":"array","items":{"type":"object","properties":{"scenarioId":{"type":"string","format":"uuid","description":"ID of the scenario to apply variables to"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Key-value pairs for this scenario"}},"required":["scenarioId","variables"]},"deprecated":true,"description":"Deprecated, for plans built on scenarios. Plans built on customer flows target them with `flowId` instead.","example":[{"scenarioId":"550e8400-e29b-41d4-a716-446655440000","variables":{"orderNumber":"12345"}},{"scenarioId":"7a3d2e1f-c4b5-6a89-0d1e-2f3a4b5c6d7e","variables":{"orderNumber":"67890"}}]}],"description":"Values for the {{variables}} the run resolves, overriding whatever the plan has pinned.\n\nAn object applies them to the whole run:\n\n  { \"orderNumber\": \"12345\", \"tier\": \"gold\" }\n\nAn array applies them per flow, or to just its happy path or one of its edge cases, when a single\nset will not do. Each entry carries what it applies to:\n\n  [\n    { \"flowId\": \"550e8400-...\", \"variables\": { \"orderNumber\": \"12345\" } },\n    { \"flowId\": \"550e8400-...\", \"happyPath\": true, \"variables\": { \"orderNumber\": \"55555\" } },\n    { \"flowId\": \"550e8400-...\", \"edgeCaseId\": \"7a3d2e1f-...\", \"variables\": { \"orderNumber\": \"67890\" } }\n  ]\n\nAn entry that narrows to neither covers everything that flow resolves. A flow this plan does not\nattach, or an edge case that does not belong to the flow, is rejected rather than ignored.\n\nA plan built on scenarios rather than customer flows targets them the same way, with `scenarioId` in\nplace of `flowId`. That form is deprecated alongside scenarios themselves, and still accepted so runs\nagainst those plans keep working."}},"description":"Optional request body for running a simulation plan with runtime variables"},"GetSimulationTemplatesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SimulationTemplate"}}},"required":["data"],"description":"The built-in simulation templates."},"SimulationTemplate":{"type":"object","properties":{"slug":{"type":"string","description":"Stable identifier. Name this in a run request.","example":"health-check"},"title":{"type":"string","description":"Display name","example":"Health check"},"description":{"type":"string","description":"What this template tests"},"category":{"type":"string","description":"Grouping used in the dashboard library","example":"Performance"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/SimulationTemplateMetricRef"},"description":"The metrics this template collects, resolved to this project's definitions."},"thresholds":{"type":"array","items":{"$ref":"#/components/schemas/SimulationTemplateMetricRef"},"description":"The Pass/Fail checks this template attaches alongside its metrics."},"flows":{"type":"array","items":{"$ref":"#/components/schemas/SimulationTemplateFlow"},"description":"The flows this template runs, and which of their ways of running it covers.\n\nEmpty means the template presets only what to measure, and a run has to say what to measure it\non: pass `flows` to POST /v1/simulation/run. When it is not empty you can still pass `flows` to\nnarrow it, naming a subset of the ids listed here."},"includeFlowMetrics":{"type":"boolean","description":"Whether runs from this template also collect each attached flow's own metrics, on top of the template's set."},"defaultMaxSimulationDurationSeconds":{"type":"integer","description":"The per-simulation cap a run from this template uses unless the request sets its own.","example":60},"defaultEndCallReasons":{"type":"array","items":{"type":"string"},"description":"The end-call conditions a run from this template uses unless the request sets its own.\n\nEmpty for templates whose calls end when the agent says goodbye. Non-empty where the template\nruns scripted flows that finish on a verdict: the simulated caller hangs up on an end-call\nphrase or one of these, so a run that discards them would stay on the line until the duration\ncap.","example":[]}},"required":["slug","title","description","category","metrics","thresholds","flows","includeFlowMetrics","defaultMaxSimulationDurationSeconds","defaultEndCallReasons"],"description":"A built-in simulation template, resolved against this project: what it measures and what it runs.","example":{"slug":"red-teaming","title":"Red teaming","description":"Adversarial probing. Tests refusals, jailbreak resistance, and whether the agent’s policy holds.","category":"Safety","metrics":[{"id":"9c1e2f3a-4b5c-4d6e-8f70-1a2b3c4d5e6f","slug":"compliance_prompt_injection_resistance"}],"thresholds":[{"id":"a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d","slug":"compliance_prompt_injection_resistance_check"}],"flows":[{"id":"550e8400-e29b-41d4-a716-446655440000","title":"Prompt injection","slug":"sf-prompt-injection","happyPath":{"title":"Direct attempt"},"edgeCases":[{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","title":"Encoded payload","slug":"data-embedded-injection"}]}],"includeFlowMetrics":false,"defaultMaxSimulationDurationSeconds":900,"defaultEndCallReasons":[]}},"SimulationTemplateMetricRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Metric definition ID"},"slug":{"type":"string","description":"Stable metric slug, e.g. \"response_time\"","example":"response_time"}},"required":["id","slug"]},"SimulationTemplateFlow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Customer flow ID"},"title":{"type":"string","description":"Flow title"},"slug":{"type":["string","null"],"description":"The stable slug of a Roark-curated flow, null for one of your own.\n\nPrefer this over `id` when you are storing a run in version control: a curated flow is a\nglobal row, so its id is the same for every project but differs between deployments, while\nthe slug is stable wherever the flow exists. Both are accepted by a run request.","example":"sf-prompt-injection"},"happyPath":{"type":["object","null"],"properties":{"title":{"type":"string"}},"required":["title"],"description":"The flow's default way of running, when this template covers it. Null when it does not, or the flow has none."},"edgeCases":{"type":"array","items":{"$ref":"#/components/schemas/SimulationTemplateEdgeCase"},"description":"The other ways of running this flow that this template covers."}},"required":["id","title","slug","happyPath","edgeCases"]},"SimulationTemplateEdgeCase":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Customer flow variant ID"},"title":{"type":"string","description":"What this way of running the flow is called"},"slug":{"type":["string","null"],"description":"The stable slug of a Roark-curated edge case, null for one of your own.\n\nPrefer this over `id` in a run you keep in version control. A curated edge case is a global\nrow, so its id differs between deployments, and renaming one replaces the row and its id\noutright. The slug survives both.","example":"data-embedded-injection"}},"required":["id","title","slug"]},"SimulationJobResponse":{"type":"object","properties":{"simulationJobId":{"type":"string","format":"uuid","description":"Simulation job ID"},"status":{"type":"string","description":"Job status"},"processingStatus":{"type":"string","description":"Processing status"},"callId":{"type":["string","null"],"format":"uuid","description":"ID of the call created for this simulation job. Null if the call has not been created yet."},"roarkPhoneNumber":{"type":["string","null"],"description":"Phone number provisioned by Roark for this simulation job in E.164 format. Null if the simulation job is queued and has not been assigned a phone number yet."},"runPlan":{"$ref":"#/components/schemas/SimulationRunPlanRef"},"enrichment":{"$ref":"#/components/schemas/SimulationJobEnrichment"},"invalidation":{"oneOf":[{"$ref":"#/components/schemas/SimulationJobInvalidation"},{"type":"null"}],"description":"Null while the result counts. See SimulationJobInvalidation."},"persona":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"]},"scenario":{"$ref":"#/components/schemas/ScenarioResponse"},"agentEndpoint":{"$ref":"#/components/schemas/AgentEndpointResponse"},"createdAt":{"type":"string","description":"When the job was created"},"startedAt":{"type":["string","null"],"description":"When the job started"},"completedAt":{"type":["string","null"],"description":"When the job completed"}},"required":["simulationJobId","status","processingStatus","runPlan","enrichment","invalidation","persona","scenario","agentEndpoint","createdAt"],"description":"Simulation job with related entities","example":{"simulationJobId":"7f3e4d2c-8a91-4b5c-9e6f-1a2b3c4d5e6f","status":"COMPLETED","processingStatus":"PROCESSED","callId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","roarkPhoneNumber":"+15551234567","runPlan":{"id":"b2c3d4e5-f6a7-8901-bcde-f12345678901","name":"Billing Flow Test","variables":{"promptToUse":"v1","accountTier":"premium"}},"enrichment":{"requested":true,"outcome":"TIMED_OUT","waitStartedAt":"2025-01-15T14:28:32.789Z","waitEndedAt":"2025-01-15T14:43:32.789Z","metricsScoredOnSimulationInstead":4,"metricsNotCollected":1},"invalidation":null,"persona":{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"Sarah Johnson - Anxious Patient","displayName":"Anxious Patient","language":"EN","secondaryLanguage":null,"understoodLanguages":["EN"],"accent":"US","age":"ADULT","gender":"FEMALE","backgroundNoise":"OFFICE","speechPace":"NORMAL","speechClarity":"CLEAR","hasDisfluencies":false,"baseEmotion":"FRUSTRATED","intentClarity":"CLEAR","confirmationStyle":"EXPLICIT","memoryReliability":"HIGH","responseTiming":"NORMAL","backstoryPrompt":"A busy professional calling during lunch break","idleMessages":null,"idleTimeoutSeconds":10,"idleMessageMaxSpokenCount":3,"idleMessageResetCountOnUserSpeechEnabled":true,"properties":{"age":"35","zipCode":"94105"},"createdAt":"2025-01-10T12:00:00.000Z","updatedAt":"2025-01-10T12:00:00.000Z"},"scenario":{"id":"f8e7d6c5-b4a3-9281-7069-5f4e3d2c1b0a","description":"Patient calling to schedule an urgent dental appointment due to severe tooth pain"},"agentEndpoint":{"id":"3c2b1a09-8f7e-6d5c-4b3a-291807060504","name":"PHONE","phoneNumber":"+15555551234","type":"PHONE"},"createdAt":"2025-01-15T14:23:45.123Z","startedAt":"2025-01-15T14:24:15.456Z","completedAt":"2025-01-15T14:28:32.789Z"}},"SimulationRunPlanRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Run plan ID"},"name":{"type":"string","description":"Run plan name"},"variables":{"type":"object","additionalProperties":{"type":"string"},"description":"Run-plan-level variables resolved for this job, keyed by variable name. Values are stringified by their declared type."}},"required":["id","name","variables"]},"SimulationJobEnrichment":{"type":"object","properties":{"requested":{"type":"boolean","description":"Whether the run plan asked for the customer's live conversation to be merged into this run."},"outcome":{"type":"string","enum":["NOT_REQUESTED","WAITING","MERGED","TIMED_OUT","SKIPPED","UNKNOWN"],"description":"How the wait for the live conversation resolved. `WAITING` means the run is holding open for it right now. `MERGED` means it arrived and live-sourced metrics were scored against it. `TIMED_OUT` and `SKIPPED` both mean it never arrived, so scoring fell back to the simulated side: read `metricsScoredOnSimulationInstead` and `metricsNotCollected` for what that cost. `UNKNOWN` is a run that finished before Roark started recording this."},"waitStartedAt":{"type":["string","null"],"description":"When the run began holding open for the live conversation. Null if it never waited."},"waitEndedAt":{"type":["string","null"],"description":"When the wait ended, however it ended. Null if it never waited or is still waiting."},"metricsScoredOnSimulationInstead":{"type":["integer","null"],"description":"Metrics that asked for the live side and were scored against the simulated side because no live conversation arrived. Null on runs that predate this recording."},"metricsNotCollected":{"type":["integer","null"],"description":"Metrics that only support the live side and so were not scored at all. Null on runs that predate this recording."}},"required":["requested","outcome"],"description":"What happened to this run's live-conversation enrichment, and what scoring fell back to when none arrived."},"GetCustomerFlowsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CustomerFlow"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"],"description":"Paginated list of customer flows"},"CustomerFlow":{"oneOf":[{"$ref":"#/components/schemas/ScriptedCustomerFlow"},{"$ref":"#/components/schemas/ImprovCustomerFlow"},{"$ref":"#/components/schemas/VoicemailCustomerFlow"}],"discriminator":{"propertyName":"type","mapping":{"SCRIPTED":"#/components/schemas/ScriptedCustomerFlow","IMPROV":"#/components/schemas/ImprovCustomerFlow","VOICEMAIL":"#/components/schemas/VoicemailCustomerFlow"}},"description":"The conversation a simulated customer has with the agent under test."},"ScriptedCustomerFlow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1},"description":{"type":["string","null"]},"source":{"type":"string","enum":["SYSTEM","CUSTOM"],"default":"CUSTOM"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"},"agents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]},"description":"The agents this flow is run against."},"agentExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectation"}},"type":{"type":"string","const":"SCRIPTED"},"scriptAdherence":{"type":"string","enum":["LOOSE","STRICT"],"description":"How closely a run follows the script. LOOSE (default) hands the whole script to the simulated customer as one prompt; it keeps the call moving whatever your agent says. STRICT runs the script as a state machine on the agent service: at every agent step the simulated customer waits, silent, until your agent has said the expected line, and only then moves on. Scripted flows only; STRICT needs the agent-service transport and is not available on realtime models."},"offScriptPolicy":{"oneOf":[{"$ref":"#/components/schemas/OffScriptPolicy"},{"type":"null"}]},"branchingMode":{"type":"string","enum":["DETERMINISTIC","ADAPTIVE"],"description":"How a run walks the graph. DETERMINISTIC (\"Simulate every path\" in the app) places one call per variant, each following its path exactly whatever the agent says. ADAPTIVE (\"Adapt to your agent\") collapses the paths into one call PER PERSONA, on which the simulated customer picks a branch from what the agent actually said. Both modes speak the exact authored lines, and neither changes how metrics or expectations grade."},"graph":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"},"description":"The conversation, as a graph of steps. Present on a single flow; omitted from the list, where reading it would mean walking the project step graph once per row."},"happyPath":{"oneOf":[{"$ref":"#/components/schemas/ScriptedFlowHappyPath"},{"type":"null"}],"description":"The way this flow is meant to go. Null when the flow has none, and then every way is an edge case."},"edgeCases":{"type":"array","items":{"$ref":"#/components/schemas/ScriptedFlowVariant"},"description":"Every other way of running this flow."}},"required":["id","title","source","createdAt","updatedAt","agents","agentExpectations","type","scriptAdherence","offScriptPolicy","branchingMode","happyPath","edgeCases"],"title":"Scripted","description":"A flow whose conversation is written out as a graph of turns."},"FlowExpectation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"prompt":{"type":"string","description":"What the agent under test is graded against."}},"required":["id","prompt"],"description":"One thing the agent under test is graded against."},"OffScriptPolicy":{"type":"object","properties":{"reaction":{"type":"string","enum":["STAY_SILENT","REPEAT","RESPOND","SAY"],"default":"STAY_SILENT"},"sayLine":{"type":["string","null"],"minLength":1,"maxLength":2000},"maxAttempts":{"type":"integer","minimum":1,"maximum":20,"default":3},"then":{"type":"string","enum":["HANG_UP","MOVE_ON","ADAPT","HANG_UP_INVALIDATE"],"default":"HANG_UP"},"waitSeconds":{"type":["integer","null"],"minimum":1,"maximum":600}},"required":["reaction","maxAttempts","then"],"description":"STRICT only. What the simulated customer does when your agent does not say the expected line. Each unmatched agent utterance is an attempt: `reaction` runs per attempt (STAY_SILENT, REPEAT its last scripted line, RESPOND once in character without moving on, or SAY `sayLine`), and `then` runs when attempts reach `maxAttempts` or your agent stays silent for `waitSeconds` (HANG_UP ends the call with ended reason SCRIPT_DIVERGED, HANG_UP_INVALIDATE ends it the same way and invalidates the run so it is scored by nothing and counted nowhere, MOVE_ON advances anyway, ADAPT hands the rest of the call to loose behaviour). Null: stay silent, 3 attempts, hang up. The default for every agent step; an AGENT_TURN step can carry its own."},"FlowStep":{"oneOf":[{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"AGENT_TURN"},"content":{"type":["string","null"]},"offScriptPolicy":{"type":["object","null"],"properties":{"reaction":{"type":"string","enum":["STAY_SILENT","REPEAT","RESPOND","SAY"],"default":"STAY_SILENT"},"sayLine":{"type":["string","null"],"minLength":1,"maxLength":2000},"maxAttempts":{"type":"integer","minimum":1,"maximum":20,"default":3},"then":{"type":"string","enum":["HANG_UP","MOVE_ON","ADAPT","HANG_UP_INVALIDATE"],"default":"HANG_UP"},"waitSeconds":{"type":["integer","null"],"minimum":1,"maximum":600}},"required":["reaction","maxAttempts","then"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"CUSTOMER_TURN"},"content":{"type":["string","null"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"CUSTOMER_FIRST_MESSAGE"},"content":{"type":["string","null"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"CUSTOMER_VERBATIM_TURN"},"content":{"type":["string","null"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"CUSTOMER_SILENCE"},"silenceDurationSeconds":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"CUSTOMER_DTMF"},"dtmfDigits":{"type":["string","null"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"AGENT_DTMF"},"dtmfDigits":{"type":["string","null"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"VOICEMAIL"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"ref":{"type":"string","minLength":1,"maxLength":64},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"mergeIntoNodeIds":{"type":"array","items":{"type":"string","minLength":1}},"type":{"type":"string","const":"SCENARIO_LINK"},"linkedCustomerFlowId":{"type":["string","null"],"format":"uuid"},"linkedCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"}},"required":["type"],"additionalProperties":false}],"description":"One step in a scripted flow's conversation.\n\n`nodeId` is the identity contract: include it to update the existing step, omit it to create a new one.\nA step continues into `steps` (more than one child is a branch point) and/or `mergeIntoNodeIds`, which\nnames steps elsewhere in the same request that this step rejoins. Branches that come back together are\nrepresented that way rather than by repeating the shared step, so reading a flow, editing it and writing\nit back preserves it exactly.\n\nA merge target is named by its `nodeId` when it already exists, or by `ref` when it is being created in\nthe same request. `ref` is a label you choose, it is request-local, and it is never stored or returned.\nPut the shared step inline under the first branch that reaches it and point the others at it: a top-level\nstep is a root wired straight from the start of the flow, so a merge target parked there would also be\nreachable directly.\n\nA `CUSTOMER_TURN` describes what the simulated customer says and the persona phrases it; a\n`CUSTOMER_VERBATIM_TURN` is said word for word, and one placed as a top-level step opens the call\nthe moment it connects, before the agent speaks. `CUSTOMER_FIRST_MESSAGE` is the retired name for\nthat opening case: still accepted, stored and returned as `CUSTOMER_VERBATIM_TURN`.\n\nThe two DTMF types are mirror images and both require `dtmfDigits`. `CUSTOMER_DTMF` is keys the\nsimulated caller presses while navigating your agent. `AGENT_DTMF` is keys your agent under test is\nexpected to press while navigating a menu the simulation is playing, so its digits are an assertion the\nrun is graded against rather than an instruction, and it counts as an agent turn for role alternation.\n\nIn a STRICT flow an `AGENT_TURN` may carry its own `offScriptPolicy`, which replaces the flow-level one at\nthat step. Omit it (or send null) to follow the flow's policy. Use it where one missed step makes the rest\nof the call meaningless: an authentication menu, say, with `then: HANG_UP_INVALIDATE`."},"ScriptedFlowVariant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1},"systemKey":{"type":["string","null"]},"precededByCustomerFlowId":{"type":["string","null"],"format":"uuid"},"precededByCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"},"isGenerated":{"type":"boolean","default":false},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"},"personaOverride":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"],"description":"The persona this runs as instead of the happy path's. Null means it inherits."},"environment":{"oneOf":[{"$ref":"#/components/schemas/EnvironmentResponse"},{"type":"null"}],"description":"The conditions this runs under. Null means it inherits the happy path's."},"additionalExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectation"},"description":"Graded on top of the flow's own expectations, for this variant only."},"type":{"type":"string","const":"SCRIPTED"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"},"description":"The one path through the graph this variant runs, in order. Linear by construction, so these steps never nest."}},"required":["id","title","precededByCustomerFlowId","precededByCustomerFlowVariantId","isGenerated","createdAt","updatedAt","personaOverride","environment","additionalExpectations","type","steps"],"title":"Scripted","description":"One path through a scripted flow. The path engine owns which paths exist, so editing the graph is what creates and removes these."},"ScriptedFlowHappyPath":{"allOf":[{"$ref":"#/components/schemas/ScriptedFlowVariant"}],"title":"Scripted","description":"One path through a scripted flow. The path engine owns which paths exist, so editing the graph is what creates and removes these."},"ImprovCustomerFlow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1},"description":{"type":["string","null"]},"source":{"type":"string","enum":["SYSTEM","CUSTOM"],"default":"CUSTOM"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"},"agents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]},"description":"The agents this flow is run against."},"agentExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectation"}},"type":{"type":"string","const":"IMPROV"},"happyPath":{"oneOf":[{"$ref":"#/components/schemas/ImprovFlowHappyPath"},{"type":"null"}],"description":"The way this flow is meant to go. Null when the flow has none, and then every way is an edge case."},"edgeCases":{"type":"array","items":{"$ref":"#/components/schemas/ImprovFlowVariant"},"description":"Every other way of running this flow."}},"required":["id","title","source","createdAt","updatedAt","agents","agentExpectations","type","happyPath","edgeCases"],"title":"Improv","description":"A flow whose conversation is not written out: each variant gives the simulated customer a brief and lets it improvise."},"ImprovFlowVariant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1},"systemKey":{"type":["string","null"]},"precededByCustomerFlowId":{"type":["string","null"],"format":"uuid"},"precededByCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"},"isGenerated":{"type":"boolean","default":false},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"},"personaOverride":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"],"description":"The persona this runs as instead of the happy path's. Null means it inherits."},"environment":{"oneOf":[{"$ref":"#/components/schemas/EnvironmentResponse"},{"type":"null"}],"description":"The conditions this runs under. Null means it inherits the happy path's."},"additionalExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectation"},"description":"Graded on top of the flow's own expectations, for this variant only."},"type":{"type":"string","const":"IMPROV"},"prompt":{"type":["string","null"],"description":"The brief the simulated customer improvises from."}},"required":["id","title","precededByCustomerFlowId","precededByCustomerFlowVariantId","isGenerated","createdAt","updatedAt","personaOverride","environment","additionalExpectations","type"],"title":"Improv","description":"One brief to run an improv flow with."},"ImprovFlowHappyPath":{"allOf":[{"$ref":"#/components/schemas/ImprovFlowVariant"}],"title":"Improv","description":"One brief to run an improv flow with."},"VoicemailCustomerFlow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1},"description":{"type":["string","null"]},"source":{"type":"string","enum":["SYSTEM","CUSTOM"],"default":"CUSTOM"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"},"agents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]},"description":"The agents this flow is run against."},"agentExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectation"}},"type":{"type":"string","const":"VOICEMAIL"},"happyPath":{"oneOf":[{"$ref":"#/components/schemas/VoicemailFlowHappyPath"},{"type":"null"}],"description":"The way this flow is meant to go. Null when the flow has none, and then every way is an edge case."},"edgeCases":{"type":"array","items":{"$ref":"#/components/schemas/VoicemailFlowVariant"},"description":"Every other way of running this flow."}},"required":["id","title","source","createdAt","updatedAt","agents","agentExpectations","type","happyPath","edgeCases"],"title":"Voicemail","description":"A flow that leaves a voicemail. Curated by Roark, read-only."},"VoicemailFlowVariant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1},"systemKey":{"type":["string","null"]},"precededByCustomerFlowId":{"type":["string","null"],"format":"uuid"},"precededByCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"},"isGenerated":{"type":"boolean","default":false},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"},"personaOverride":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"],"description":"The persona this runs as instead of the happy path's. Null means it inherits."},"environment":{"oneOf":[{"$ref":"#/components/schemas/EnvironmentResponse"},{"type":"null"}],"description":"The conditions this runs under. Null means it inherits the happy path's."},"additionalExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectation"},"description":"Graded on top of the flow's own expectations, for this variant only."},"type":{"type":"string","const":"VOICEMAIL"}},"required":["id","title","precededByCustomerFlowId","precededByCustomerFlowVariantId","isGenerated","createdAt","updatedAt","personaOverride","environment","additionalExpectations","type"],"title":"Voicemail","description":"One voicemail greeting."},"VoicemailFlowHappyPath":{"allOf":[{"$ref":"#/components/schemas/VoicemailFlowVariant"}],"title":"Voicemail","description":"One voicemail greeting."},"CreateCustomerFlowInput":{"oneOf":[{"$ref":"#/components/schemas/CreateScriptedCustomerFlowInput"},{"$ref":"#/components/schemas/CreateImprovCustomerFlowInput"}],"discriminator":{"propertyName":"type","mapping":{"SCRIPTED":"#/components/schemas/CreateScriptedCustomerFlowInput","IMPROV":"#/components/schemas/CreateImprovCustomerFlowInput"}},"description":"Input for creating a customer flow. SCRIPTED writes the conversation out as a graph of turns; IMPROV gives the simulated customer a brief and lets it improvise."},"CreateScriptedCustomerFlowInput":{"type":"object","properties":{"type":{"type":"string","const":"SCRIPTED"},"title":{"type":"string","minLength":1,"example":"Reschedule an appointment"},"description":{"type":["string","null"]},"agentExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectationInput"}},"agentIds":{"type":"array","items":{"type":"string","format":"uuid"},"default":[],"description":"Agents this flow exercises. Optional for scripted flows."},"scriptAdherence":{"type":"string","enum":["LOOSE","STRICT"],"description":"How closely a run follows the script. LOOSE (default) hands the whole script to the simulated customer as one prompt; it keeps the call moving whatever your agent says. STRICT runs the script as a state machine on the agent service: at every agent step the simulated customer waits, silent, until your agent has said the expected line, and only then moves on. Scripted flows only; STRICT needs the agent-service transport and is not available on realtime models. (LOOSE is the default.)"},"offScriptPolicy":{"oneOf":[{"$ref":"#/components/schemas/OffScriptPolicy"},{"type":"null"}]},"branchingMode":{"type":"string","enum":["DETERMINISTIC","ADAPTIVE"],"description":"How a run walks the graph. DETERMINISTIC (\"Simulate every path\" in the app) places one call per variant, each following its path exactly whatever the agent says. ADAPTIVE (\"Adapt to your agent\") collapses the paths into one call PER PERSONA, on which the simulated customer picks a branch from what the agent actually said. Both modes speak the exact authored lines, and neither changes how metrics or expectations grade. (DETERMINISTIC is the default.)"},"graph":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"},"minItems":1,"description":"The conversation, as a graph of steps. At most 100 steps across at most 25 paths. The variants come from the graph: one per path, so they are not sent here. A CUSTOMER_TURN describes what the simulated customer says and the persona phrases it; a CUSTOMER_VERBATIM_TURN is said word for word."}},"required":["type","title","graph"],"title":"Scripted","example":{"type":"SCRIPTED","title":"Reschedule an appointment","agentIds":["7c9e6679-7425-40de-944b-e07fc1f90ae7"],"graph":[{"type":"CUSTOMER_VERBATIM_TURN","content":"Hi, I need to move my appointment.","steps":[{"type":"AGENT_TURN","content":"Offers alternative times","steps":[{"type":"CUSTOMER_TURN","content":"Takes the first slot"},{"type":"CUSTOMER_TURN","content":"Asks for later in the week"}]}]}]}},"FlowExpectationInput":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"What the agent under test is graded against.","example":"The agent confirmed the new appointment time back to the customer"}},"required":["prompt"]},"CreateImprovCustomerFlowInput":{"type":"object","properties":{"type":{"type":"string","const":"IMPROV"},"title":{"type":"string","minLength":1,"example":"Reschedule an appointment"},"description":{"type":["string","null"]},"agentExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectationInput"}},"agentIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"description":"Agents this flow exercises. At least one is required for improv flows."},"happyPath":{"$ref":"#/components/schemas/FlowHappyPathInput"},"edgeCases":{"type":"array","items":{"$ref":"#/components/schemas/FlowEdgeCaseInput"},"description":"Other ways of running it, each inheriting from the happy path what it does not name."}},"required":["type","title","agentIds","happyPath"],"title":"Improv","example":{"type":"IMPROV","title":"Billing questions","agentIds":["7c9e6679-7425-40de-944b-e07fc1f90ae7"],"agentExpectations":[{"prompt":"The agent never states an amount it has not verified"}],"happyPath":{"title":"Asks about a charge","personaOverrideId":"6ba7b810-9dad-11d1-80b4-00c04fd430c8","environmentId":"d1f5c19d-0000-4000-8000-000000000001","prompt":"You want to understand a charge on your latest invoice."},"edgeCases":[{"title":"Disputes the charge","prompt":"You are certain the charge is wrong."}]}},"FlowHappyPathInput":{"type":"object","properties":{"title":{"type":"string","minLength":1},"environmentId":{"type":"string","format":"uuid","description":"The conditions this flow runs under. Edge cases inherit them unless they name their own."},"prompt":{"type":["string","null"]},"precededByCustomerFlowId":{"type":["string","null"],"format":"uuid"},"precededByCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"},"personaOverrideId":{"type":"string","format":"uuid","description":"The persona this flow runs as. Edge cases inherit it unless they name their own."}},"required":["title","environmentId","personaOverrideId"],"description":"The way this flow is meant to go."},"FlowEdgeCaseInput":{"type":"object","properties":{"title":{"type":"string","minLength":1},"environmentId":{"type":["string","null"],"format":"uuid"},"prompt":{"type":["string","null"]},"precededByCustomerFlowId":{"type":["string","null"],"format":"uuid"},"precededByCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"},"personaOverrideId":{"type":["string","null"],"format":"uuid","description":"The persona this runs as. Omit to inherit the happy path's."}},"required":["title"]},"UpdateCustomerFlowInput":{"type":"object","properties":{"title":{"type":"string","minLength":1},"description":{"type":["string","null"]},"scriptAdherence":{"type":"string","enum":["LOOSE","STRICT"],"description":"Scripted flows only. How closely a run follows the script. LOOSE (default) hands the whole script to the simulated customer as one prompt; it keeps the call moving whatever your agent says. STRICT runs the script as a state machine on the agent service: at every agent step the simulated customer waits, silent, until your agent has said the expected line, and only then moves on. Scripted flows only; STRICT needs the agent-service transport and is not available on realtime models."},"offScriptPolicy":{"oneOf":[{"$ref":"#/components/schemas/OffScriptPolicy"},{"type":"null"}]},"branchingMode":{"type":"string","enum":["DETERMINISTIC","ADAPTIVE"],"description":"Scripted flows only. How a run walks the graph. DETERMINISTIC (\"Simulate every path\" in the app) places one call per variant, each following its path exactly whatever the agent says. ADAPTIVE (\"Adapt to your agent\") collapses the paths into one call PER PERSONA, on which the simulated customer picks a branch from what the agent actually said. Both modes speak the exact authored lines, and neither changes how metrics or expectations grade."},"agentIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Replaces the linked agents. Omit to leave them unchanged. An improv flow must keep at least one; a scripted flow can be left with none."},"agentExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectationInput"},"description":"Replaces the flow-level expectations. Omit to leave them unchanged."}},"description":"Fields to change on a customer flow. The step graph is edited through PUT /graph instead."},"ReplaceFlowStepsResponse":{"type":"object","properties":{"graph":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"}},"variantsReshaped":{"type":"boolean","description":"True when the write changed the set of paths, so the flow's variants were re-seeded and any variant id you were holding may no longer exist."},"happyPath":{"oneOf":[{"$ref":"#/components/schemas/FlowHappyPath"},{"type":"null"}],"description":"The happy path after the write."},"edgeCases":{"type":"array","items":{"$ref":"#/components/schemas/FlowVariant"},"description":"The edge cases after the write."},"warnings":{"type":"array","items":{"type":"string"}}},"required":["graph","variantsReshaped","happyPath","edgeCases","warnings"]},"FlowHappyPath":{"oneOf":[{"$ref":"#/components/schemas/ScriptedFlowHappyPath"},{"$ref":"#/components/schemas/ImprovFlowHappyPath"},{"$ref":"#/components/schemas/VoicemailFlowHappyPath"}],"discriminator":{"propertyName":"type","mapping":{"SCRIPTED":"#/components/schemas/ScriptedFlowHappyPath","IMPROV":"#/components/schemas/ImprovFlowHappyPath","VOICEMAIL":"#/components/schemas/VoicemailFlowHappyPath"}},"description":"The way a customer flow is meant to go."},"FlowVariant":{"oneOf":[{"$ref":"#/components/schemas/ScriptedFlowVariant"},{"$ref":"#/components/schemas/ImprovFlowVariant"},{"$ref":"#/components/schemas/VoicemailFlowVariant"}],"discriminator":{"propertyName":"type","mapping":{"SCRIPTED":"#/components/schemas/ScriptedFlowVariant","IMPROV":"#/components/schemas/ImprovFlowVariant","VOICEMAIL":"#/components/schemas/VoicemailFlowVariant"}},"description":"One way of running a customer flow."},"ReplaceFlowStepsInput":{"type":"object","properties":{"graph":{"type":"array","items":{"$ref":"#/components/schemas/FlowStep"},"minItems":1,"description":"The complete graph. This replaces the flow's existing steps rather than merging into them."},"allowUnmerge":{"type":"boolean","description":"Confirms a write that drops branches which currently rejoin. Only needed when the request omits mergeIntoNodeIds references the flow already had; a faithful round trip never needs it."}},"required":["graph"]},"UpdateFlowVariantInput":{"type":"object","properties":{"title":{"type":"string","minLength":1},"environmentId":{"type":["string","null"],"format":"uuid"},"prompt":{"type":["string","null"]},"precededByCustomerFlowId":{"type":["string","null"],"format":"uuid"},"precededByCustomerFlowVariantId":{"type":["string","null"],"format":"uuid"},"personaOverrideId":{"type":["string","null"],"format":"uuid","description":"The persona this runs as. Null on an edge case inherits the happy path's."},"additionalExpectations":{"type":"array","items":{"$ref":"#/components/schemas/FlowExpectationInput"},"description":"Replaces the expectations that apply to this variant on top of the flow's. Omit to leave them alone, send [] to clear. Improv flows only: a scripted variant's expectations come from the agent turns on its path and are rewritten on the next graph edit."}},"description":"Fields to change on a variant. Omitted fields are left alone. Making a variant the default is a separate operation, since it also demotes the current default."},"AddFlowEdgeCaseInput":{"$ref":"#/components/schemas/FlowEdgeCaseInput"},"HttpRequestDefinitionResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"HTTP request definition ID"},"scope":{"type":"string","enum":["AGENT_OUTBOUND_DIAL"],"description":"Scope of the HTTP request definition"},"description":{"type":["string","null"],"description":"Description of the HTTP request definition"},"url":{"type":"string","description":"URL for the HTTP request"},"method":{"type":"string","enum":["POST","PUT","PATCH","GET"],"description":"HTTP method: POST, PUT, PATCH, or GET"},"body":{"type":["string","null"],"description":"Request body as a string"},"parsedBody":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"string"},{"type":"null"}],"description":"Parsed body as a JSON object if valid JSON, otherwise the raw string"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Request headers as key-value pairs"},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","scope","description","url","method","body","parsedBody","headers","createdAt","updatedAt"],"description":"HTTP request definition"},"HttpRequestDefinitionCreateResponse":{"allOf":[{"$ref":"#/components/schemas/HttpRequestDefinitionResponse"}],"properties":{"signingSecret":{"type":"string","description":"Signing secret (only returned on creation)"}},"required":["signingSecret"],"description":"HTTP request definition with signing secret (returned on creation)"},"CreateHttpRequestDefinitionInput":{"type":"object","properties":{"scope":{"type":"string","enum":["AGENT_OUTBOUND_DIAL"],"description":"Scope: AGENT_OUTBOUND_DIAL"},"url":{"type":"string","format":"uri","description":"URL for the HTTP request"},"description":{"type":["string","null"],"description":"Description of the HTTP request definition"},"method":{"type":"string","enum":["POST","PUT","PATCH","GET"],"default":"POST","description":"HTTP method (default: POST)"},"body":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"Request body template. Accepts a JSON object or a string with placeholders like {{phoneNumberToDial}}. Objects are serialized to JSON for storage."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Request headers as key-value pairs"}},"required":["scope","url"],"description":"Input for creating an HTTP request definition"},"UpdateHttpRequestDefinitionInput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL for the HTTP request"},"description":{"type":["string","null"],"description":"Description of the HTTP request definition"},"method":{"type":"string","enum":["POST","PUT","PATCH","GET"],"description":"HTTP method: POST, PUT, PATCH, or GET"},"body":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"Request body template. Accepts a JSON object or a string with placeholders like {{phoneNumberToDial}}. Objects are serialized to JSON for storage."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Request headers as key-value pairs"}},"description":"Input for updating an HTTP request definition"},"WebhookResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Webhook ID"},"description":{"type":["string","null"],"description":"Webhook description"},"url":{"type":"string","description":"Webhook URL"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Request headers"},"events":{"type":"array","items":{"type":"string","enum":["CALL_ANALYSIS_COMPLETED","CALL_ANALYSIS_FAILED","CALL_ANALYSIS_CANCELLED","CALL_EVALUATION_COMPLETED","CALL_EVALUATION_FAILED","SIMULATION_RUN_PLAN_JOB_STARTED","SIMULATION_RUN_PLAN_JOB_COMPLETED","SIMULATION_RUN_PLAN_JOB_FAILED","SIMULATION_RUN_PLAN_JOB_CANCELLED","SIMULATION_JOB_STARTED","SIMULATION_JOB_COMPLETED","SIMULATION_JOB_FAILED","SIMULATION_JOB_CANCELLED","METRIC_COLLECTION_JOB_COMPLETED","METRIC_COLLECTION_JOB_FAILED","CHAT_ANALYSIS_COMPLETED","CHAT_ANALYSIS_FAILED","ISSUE_OPENED","ISSUE_RESOLVED"]},"description":"Event types this webhook is subscribed to"},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","description","url","headers","events","createdAt","updatedAt"],"description":"Webhook with its subscribed event types"},"CreateWebhookResponse":{"allOf":[{"$ref":"#/components/schemas/WebhookResponse"}],"properties":{"signingSecret":{"type":"string","description":"Signing secret (only returned on creation)"}},"required":["signingSecret"],"description":"Webhook response with signing secret (returned on creation)"},"CreateWebhookInput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Webhook URL"},"description":{"type":["string","null"],"description":"Webhook description"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Request headers (e.g. authorization tokens)"},"events":{"type":"array","items":{"type":"string","enum":["CALL_ANALYSIS_COMPLETED","CALL_ANALYSIS_FAILED","CALL_ANALYSIS_CANCELLED","CALL_EVALUATION_COMPLETED","CALL_EVALUATION_FAILED","SIMULATION_RUN_PLAN_JOB_STARTED","SIMULATION_RUN_PLAN_JOB_COMPLETED","SIMULATION_RUN_PLAN_JOB_FAILED","SIMULATION_RUN_PLAN_JOB_CANCELLED","SIMULATION_JOB_STARTED","SIMULATION_JOB_COMPLETED","SIMULATION_JOB_FAILED","SIMULATION_JOB_CANCELLED","METRIC_COLLECTION_JOB_COMPLETED","METRIC_COLLECTION_JOB_FAILED","CHAT_ANALYSIS_COMPLETED","CHAT_ANALYSIS_FAILED","ISSUE_OPENED","ISSUE_RESOLVED"]},"minItems":1,"description":"Event types to subscribe to (at least one required)"}},"required":["url","events"],"description":"Input for creating a webhook"},"Issue":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"alertId":{"type":["string","null"],"format":"uuid","description":"Only set when source is an alert"},"source":{"type":"string","enum":["TREND_ALERT","SINGLE_CALL_ALERT","TRACE_FAILURE","MANUAL","API","AGENT"],"description":"Who opened the issue"},"title":{"type":"string"},"summary":{"type":["string","null"]},"severity":{"type":["string","null"],"enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Coarse priority — LOW / MEDIUM / HIGH / CRITICAL"},"status":{"type":"string","enum":["OPEN","ACKED","RESOLVED"],"description":"Lifecycle state"},"fingerprint":{"type":"string","description":"Producer-supplied dedup key. Same fingerprint coalesces into the same issue."},"eventCount":{"type":"integer","description":"How many times this issue has been observed."},"lastEventAt":{"type":["string","null"],"description":"Timestamp of the most recent occurrence, or null if no events yet."},"openedAt":{"type":"string"},"resolvedAt":{"type":["string","null"]},"assigneeUserId":{"type":["string","null"],"format":"uuid"},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/IssueEvidence"},"description":"Calls / chats attached as evidence"},"createdAt":{"type":"string"},"updatedAt":{"type":["string","null"]}},"required":["id","organizationId","projectId","alertId","source","title","summary","severity","status","fingerprint","eventCount","lastEventAt","openedAt","resolvedAt","assigneeUserId","evidence","createdAt","updatedAt"],"description":"An issue surfaced on the Roark Issues page"},"IssueEvidence":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"callId":{"type":["string","null"],"format":"uuid","description":"Call attached as evidence, or null"},"chatId":{"type":["string","null"],"format":"uuid","description":"Chat attached as evidence, or null"},"observedAt":{"type":"string","description":"When the evidence was observed (ISO-8601)"}},"required":["id","callId","chatId","observedAt"]},"CreateIssueInput":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":280,"description":"Short headline — required, max 280 characters"},"summary":{"type":["string","null"],"minLength":1,"maxLength":2000,"description":"Longer-form context — optional, max 2000 characters"},"severity":{"type":["string","null"],"enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Coarse priority. Null when unset."},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/CreateIssueEvidence"},"maxItems":50,"default":[],"description":"Calls / chats to attach as evidence. Optional; max 50 entries per issue."}},"required":["title"]},"CreateIssueEvidence":{"type":"object","properties":{"callId":{"type":"string","format":"uuid"},"chatId":{"type":"string","format":"uuid"}},"description":"A call or chat to attach as evidence (exactly one of `callId` / `chatId`)"},"ConfigDiffResponse":{"type":"object","properties":{"changes":{"type":"array","items":{"$ref":"#/components/schemas/ConfigDiffChange"}},"summary":{"$ref":"#/components/schemas/ConfigDiffSummary"}},"required":["changes","summary"]},"ConfigDiffChange":{"type":"object","properties":{"configKey":{"type":"string"},"kind":{"type":"string","enum":["agent","persona","flow","collector","metric","simulationPlan","alert"]},"name":{"type":"string"},"op":{"type":"string","enum":["create","update","delete","noop"]},"detail":{"type":"string"}},"required":["configKey","kind","name","op"]},"ConfigDiffSummary":{"type":"object","properties":{"create":{"type":"integer"},"update":{"type":"integer"},"delete":{"type":"integer"},"noop":{"type":"integer"}},"required":["create","update","delete","noop"]},"ConfigBundle":{"type":"object","properties":{"resources":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/AgentConfig"},{"$ref":"#/components/schemas/PersonaConfig"},{"$ref":"#/components/schemas/ImprovFlowConfig"},{"$ref":"#/components/schemas/ScriptedFlowConfig"},{"$ref":"#/components/schemas/CollectorConfig"},{"$ref":"#/components/schemas/MetricConfig"},{"$ref":"#/components/schemas/SimulationPlanConfig"},{"$ref":"#/components/schemas/AlertConfig"}]}},"prune":{"type":"boolean","default":true}},"required":["resources"]},"AgentConfig":{"type":"object","properties":{"kind":{"type":"string","const":"agent"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"displayName":{"type":"string"},"description":{"type":["string","null"]},"customId":{"type":["string","null"]},"endpoints":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string","minLength":1},"type":{"type":"string","enum":["PHONE","WEBSOCKET"],"default":"PHONE"},"direction":{"type":"string","enum":["INCOMING","OUTGOING","INCOMING_AND_OUTGOING"],"default":"INCOMING"},"environment":{"type":"string"}},"required":["value"]}},"prompt":{"type":["string","null"]}},"required":["kind","name"]},"PersonaConfig":{"type":"object","properties":{"kind":{"type":"string","const":"persona"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"displayName":{"type":"string"},"description":{"type":["string","null"]},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"secondaryLanguage":{"type":["string","null"],"const":"EN"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"]},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT"},"gender":{"type":"string","enum":["MALE","FEMALE"]},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR"},"hasDisfluencies":{"type":"boolean","default":false},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL"},"backstoryPrompt":{"type":["string","null"]},"idleMessages":{"type":["array","null"],"items":{"type":"string"}},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true},"properties":{"type":"object","additionalProperties":{}}},"required":["kind","name","language","accent","gender"]},"ImprovFlowConfig":{"type":"object","properties":{"kind":{"type":"string","const":"flow"},"type":{"type":"string","const":"improv"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"title":{"type":"string"},"description":{"type":["string","null"]},"agents":{"type":"array","items":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"minItems":1},"expectations":{"type":"array","items":{"type":"string"}},"happyPath":{"type":"object","properties":{"persona":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"environment":{"type":"string"},"prompt":{"type":"string"},"expectations":{"type":"array","items":{"type":"string"}},"title":{"type":"string"}},"required":["persona","environment"]},"edgeCases":{"type":"array","items":{"type":"object","properties":{"persona":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"environment":{"type":"string"},"prompt":{"type":"string"},"expectations":{"type":"array","items":{"type":"string"}},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"title":{"type":"string"}},"required":["name"]}}},"required":["kind","type","name","agents","happyPath"]},"ScriptedFlowConfig":{"type":"object","properties":{"kind":{"type":"string","const":"flow"},"type":{"type":"string","const":"scripted"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"title":{"type":"string"},"description":{"type":["string","null"]},"agents":{"type":"array","items":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1}},"branchingMode":{"type":"string","enum":["DETERMINISTIC","ADAPTIVE"]},"adherence":{"type":"string","enum":["LOOSE","STRICT"]},"offScript":{"$ref":"#/components/schemas/ConfigOffScript"},"expectations":{"type":"array","items":{"type":"string"}},"graph":{"type":"array","items":{"$ref":"#/components/schemas/ConfigFlowStep"},"minItems":1}},"required":["kind","type","name","graph"]},"ConfigOffScript":{"type":"object","properties":{"reaction":{"type":"string","enum":["STAY_SILENT","REPEAT","RESPOND","SAY"]},"sayLine":{"type":"string","minLength":1,"maxLength":2000},"maxAttempts":{"type":"integer","minimum":1,"maximum":20},"then":{"type":"string","enum":["HANG_UP","MOVE_ON","ADAPT","HANG_UP_INVALIDATE"]},"waitSeconds":{"type":"integer","minimum":1,"maximum":600}}},"ConfigFlowStep":{"type":"object","properties":{"ref":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["AGENT_TURN","CUSTOMER_TURN","CUSTOMER_FIRST_MESSAGE","CUSTOMER_VERBATIM_TURN","CUSTOMER_SILENCE","CUSTOMER_DTMF","AGENT_DTMF","VOICEMAIL","SCENARIO_LINK"]},"content":{"type":"string"},"offScript":{"$ref":"#/components/schemas/ConfigOffScript"},"silenceDurationSeconds":{"type":"integer","exclusiveMinimum":0},"dtmfDigits":{"type":"string"},"flow":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"mergeInto":{"type":"array","items":{"type":"string","minLength":1}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/ConfigFlowStep"}}},"required":["type"]},"CollectorConfig":{"type":"object","properties":{"kind":{"type":"string","const":"collector"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"modality":{"type":"string","enum":["call","chat"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE"],"default":"ACTIVE"},"metrics":{"type":"array","items":{"type":"string","minLength":1},"minItems":1},"filters":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["AGENT","CALL_SOURCE","CALL_PROPERTY","INTEGRATION"]},"key":{"type":"string","minLength":1},"operator":{"type":"string","enum":["EQUALS","NOT_EQUALS","CONTAINS","STARTS_WITH","GREATER_THAN","LESS_THAN","GREATER_THAN_OR_EQUALS","LESS_THAN_OR_EQUALS"]},"value":{"type":"string"}},"required":["type","key"]},"minItems":1}},"required":["conditions"]}}},"required":["kind","name","modality","metrics"]},"MetricConfig":{"type":"object","properties":{"kind":{"type":"string","const":"metric"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"displayName":{"type":"string","minLength":1,"maxLength":100},"type":{"type":"string","enum":["BOOLEAN","SCALE","NUMERIC","TEXT","CLASSIFICATION"]},"prompt":{"type":"string","minLength":1},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"default":"GLOBAL"},"participantRole":{"type":"string","enum":["AGENT","CUSTOMER"]},"contexts":{"type":"array","items":{"type":"string","enum":["CALL","SEGMENT","TURN"]},"minItems":1,"default":["CALL"]},"trueLabel":{"type":"string"},"falseLabel":{"type":"string"},"scaleMin":{"type":"integer"},"scaleMax":{"type":"integer"},"scaleLabels":{"type":"array","items":{"type":"object","properties":{"rangeMin":{"type":"number"},"rangeMax":{"type":"number"},"label":{"type":"string","minLength":1},"description":{"type":"string"},"displayOrder":{"type":"integer"},"colorHex":{"type":"string"}},"required":["rangeMin","rangeMax","label","displayOrder"]}},"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"description":{"type":"string"},"displayOrder":{"type":"integer"}},"required":["label","displayOrder"]},"minItems":1},"maxSelections":{"type":"integer","minimum":1}},"required":["kind","name","type","prompt"]},"SimulationPlanConfig":{"type":"object","properties":{"kind":{"type":"string","const":"simulationPlan"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"description":{"type":["string","null"]},"direction":{"type":"string","enum":["INBOUND","OUTBOUND"]},"agentEndpoints":{"type":"array","items":{"$ref":"#/components/schemas/SimulationPlanAgentEndpointConfig"},"minItems":1},"metrics":{"type":"array","items":{"type":"string","minLength":1},"minItems":1},"flows":{"type":"array","items":{"$ref":"#/components/schemas/SimulationPlanFlowConfig"},"minItems":1},"maxDurationSeconds":{"type":"integer","minimum":1},"iterations":{"type":"integer","minimum":1,"maximum":10000,"default":1},"maxConcurrentJobs":{"type":"integer","minimum":1,"default":1},"executionMode":{"type":"string","enum":["PARALLEL","SEQUENTIAL_SAME_RUN_PLAN","SEQUENTIAL_PROJECT"],"default":"PARALLEL"},"silenceTimeoutSeconds":{"type":"integer","minimum":1,"default":30},"endCallPhrases":{"type":"array","items":{"type":"string","minLength":1},"maxItems":10,"default":["goodbye"]},"endCallReasons":{"type":"array","items":{"type":"string","minLength":1},"maxItems":10,"default":[]},"includeFlowMetrics":{"type":"boolean","default":true},"includeAutomaticMetrics":{"type":"boolean","default":true},"enrichWithLiveConversation":{"type":"boolean","default":false}},"required":["kind","name","direction","agentEndpoints","metrics","flows","maxDurationSeconds"]},"SimulationPlanAgentEndpointConfig":{"type":"object","properties":{"agent":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"value":{"type":"string","minLength":1},"direction":{"type":"string","enum":["INCOMING","OUTGOING","INCOMING_AND_OUTGOING"]}},"required":["agent"]},"SimulationPlanFlowConfig":{"type":"object","properties":{"flow":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"system":{"type":"string","minLength":1},"happyPath":{"type":"boolean"},"edgeCases":{"type":"array","items":{"type":"string","minLength":1}},"personaOverride":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1}}},"AlertConfig":{"type":"object","properties":{"kind":{"type":"string","const":"alert"},"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"enabled":{"type":"boolean","default":true},"trigger":{"oneOf":[{"$ref":"#/components/schemas/AlertThresholdTrigger"},{"$ref":"#/components/schemas/AlertEventTrigger"},{"$ref":"#/components/schemas/AlertSimulationTrigger"}],"discriminator":{"propertyName":"type","mapping":{"threshold":"#/components/schemas/AlertThresholdTrigger","event":"#/components/schemas/AlertEventTrigger","simulation":"#/components/schemas/AlertSimulationTrigger"}}},"actions":{"$ref":"#/components/schemas/AlertActions"}},"required":["kind","name","trigger"]},"AlertThresholdTrigger":{"type":"object","properties":{"type":{"type":"string","const":"threshold"},"metric":{"type":"string","minLength":1},"metricVariant":{"type":"string","minLength":1},"aggregation":{"type":"string","enum":["COUNT","RATE_PER_MINUTE","MEAN"]},"windowMinutes":{"type":"integer","exclusiveMinimum":0},"operator":{"type":"string","enum":["GT","GTE","LT","LTE"]},"thresholdValue":{"type":"number"},"grouping":{"type":"string","enum":["NONE","BY_AGENT"],"default":"NONE"},"minSampleSize":{"type":"integer","minimum":1,"default":1},"consecutiveOpen":{"type":"integer","minimum":1,"default":2},"consecutiveResolve":{"type":"integer","minimum":1,"default":3}},"required":["type","metric","aggregation","windowMinutes","operator","thresholdValue"]},"AlertEventTrigger":{"type":"object","properties":{"type":{"type":"string","const":"event"},"events":{"type":"array","items":{"type":"string","enum":["CALL_ANALYSIS_COMPLETED","CALL_ANALYSIS_FAILED","CALL_ANALYSIS_CANCELLED","SIMULATION_RUN_PLAN_JOB_STARTED","SIMULATION_RUN_PLAN_JOB_COMPLETED","SIMULATION_RUN_PLAN_JOB_FAILED","SIMULATION_RUN_PLAN_JOB_CANCELLED","SIMULATION_JOB_STARTED","SIMULATION_JOB_COMPLETED","SIMULATION_JOB_FAILED","SIMULATION_JOB_CANCELLED","METRIC_COLLECTION_JOB_COMPLETED","METRIC_COLLECTION_JOB_FAILED","CHAT_ANALYSIS_COMPLETED","CHAT_ANALYSIS_FAILED","ISSUE_OPENED","ISSUE_RESOLVED"]},"minItems":1}},"required":["type","events"]},"AlertSimulationTrigger":{"type":"object","properties":{"type":{"type":"string","const":"simulation"},"conditions":{"type":"array","items":{"type":"string","enum":["SUCCESS","FAILURE","THRESHOLD_FAILED"]},"minItems":1},"plan":{"type":"string","pattern":"^[a-z0-9][a-z0-9-_.]*$","minLength":1},"deliveryFormat":{"type":"string","enum":["MESSAGE","PDF"],"default":"MESSAGE"}},"required":["type","conditions"]},"AlertActions":{"type":"object","properties":{"slack":{"type":"array","items":{"$ref":"#/components/schemas/AlertSlackChannel"}},"webhooks":{"type":"array","items":{"type":"string","format":"uri"}}}},"AlertSlackChannel":{"type":"object","properties":{"channelId":{"type":"string","minLength":1},"channelName":{"type":"string","minLength":1}},"required":["channelId","channelName"]},"ConfigApplyResponse":{"type":"object","properties":{"changes":{"type":"array","items":{"$ref":"#/components/schemas/ConfigApplyChange"}},"summary":{"$ref":"#/components/schemas/ConfigApplySummary"}},"required":["changes","summary"]},"ConfigApplyChange":{"allOf":[{"$ref":"#/components/schemas/ConfigDiffChange"}],"properties":{"status":{"type":"string","enum":["applied","skipped","failed"]},"id":{"type":"string"},"error":{"type":"string"}},"required":["status"]},"ConfigApplySummary":{"allOf":[{"$ref":"#/components/schemas/ConfigDiffSummary"}],"properties":{"failed":{"type":"integer"}},"required":["failed"]},"CallAnalysisResponse":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid","description":"Analysis job ID for tracking progress"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","FAILED","CANCELLED","AWAITING_CREDIT"]},"call":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":["string","null"],"enum":["RINGING","IN_PROGRESS","ENDED"],"default":"IN_PROGRESS"},"summary":{"type":["string","null"]},"callDirection":{"type":"string","enum":["INBOUND","OUTBOUND"],"default":"INBOUND"},"startedAt":{"type":"string"},"endedAt":{"type":["string","null"]},"durationMs":{"type":["number","null"]},"endedReason":{"type":["string","null"]},"isTest":{"type":"boolean","default":false},"participants":{"type":"array","items":{"type":"object","properties":{"participantId":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1},"phoneNumber":{"type":["string","null"],"minLength":3},"role":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"spokeFirst":{"type":"boolean"},"isSimulated":{"type":"boolean"}},"required":["role"]},"minItems":1},"properties":{"type":["object","null"],"additionalProperties":{}}},"required":["id","status","callDirection","startedAt","isTest","participants"]}},"required":["jobId","status","call"],"description":"Analysis job with associated call context"},"CallAnalysisCreate":{"type":"object","properties":{"recordingUrl":{"type":"string","format":"uri","description":"URL of source recording (must be an accessible WAV, MP3, MP4, or OGG file). Can be a signed URL."},"startedAt":{"type":"string","description":"When the call started (ISO 8601 format)"},"interfaceType":{"type":"string","enum":["PHONE","WEB"],"description":"Interface type of the call (PHONE or WEB)"},"callDirection":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the call (INBOUND or OUTBOUND)"},"participants":{"type":"array","items":{"type":"object","properties":{"participantId":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1},"phoneNumber":{"type":["string","null"],"minLength":3},"role":{"type":"string","enum":["AGENT","CUSTOMER","SIMULATED_CUSTOMER","BACKGROUND_SPEAKER"]},"spokeFirst":{"type":"boolean"},"isSimulated":{"type":"boolean"}},"required":["role"]},"minItems":1,"description":"Exactly two participants in the call"},"stereoRecordingUrl":{"type":"string","format":"uri","description":"URL of source stereo recording. Must be accessible. Can be a signed URL. While optional it allows for a richer audio player. Supported formats: WAV, MP3, MP4, OGG."},"endedStatus":{"type":"string","enum":["PARTICIPANTS_DID_NOT_SPEAK","AGENT_DID_NOT_ANSWER","AGENT_DID_NOT_SPEAK","AGENT_STOPPED_SPEAKING","AGENT_ENDED_CALL","AGENT_TRANSFERRED_CALL","AGENT_BUSY","AGENT_ERROR","CUSTOMER_ENDED_CALL","VOICE_MAIL_REACHED","SILENCE_TIME_OUT","PHONE_CALL_PROVIDER_CONNECTION_ERROR","CUSTOMER_DID_NOT_ANSWER","CUSTOMER_DID_NOT_SPEAK","CUSTOMER_STOPPED_SPEAKING","CUSTOMER_BUSY","DIAL_ERROR","MAX_DURATION_REACHED","UNKNOWN"],"description":"High-level call end status, indicating how the call terminated"},"endedReason":{"type":"string","description":"Additional context on why the call terminated with the endedStatus"},"toolInvocations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the tool that was invoked"},"description":{"type":"string","description":"Description of when the tool should be invoked"},"parameters":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"description":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean"]},"value":{}}},{}],"examples":["value",{"value":"cleaning","description":"Type of dental appointment","type":"string"}]},"description":"Parameters provided to the tool during invocation"},"result":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{}}],"description":"Result returned by the tool after execution. Can be a string or a JSON object"},"startOffsetMs":{"type":"integer","description":"Offset in milliseconds from the start of the call when the tool was invoked"},"endOffsetMs":{"type":"integer","description":"Offset in milliseconds from the start of the call when the tool execution completed. Used to calculate duration of the tool execution"}},"required":["name","parameters","result","startOffsetMs"]},"description":"List of tool invocations made during the call"},"isTest":{"type":"boolean","description":"Whether this is a test call"},"vapiCallId":{"type":"string","format":"uuid","description":"Vapi call ID if call is being imported from Vapi"},"retellCallId":{"type":"string","description":"Retell call ID if call is being imported from Retell"},"properties":{"type":"object","additionalProperties":{},"description":"Custom properties to include with the call. These can be used for filtering and will show in the call details page"}},"required":["recordingUrl","startedAt","interfaceType","callDirection","participants"],"description":"Call analysis creation payload","example":{"recordingUrl":"https://example.com/recording.wav","callDirection":"INBOUND","interfaceType":"WEB","startedAt":"2026-05-18T09:44:40.971Z","isTest":false,"participants":[{"name":"Sales Agent","phoneNumber":"+15551234567","role":"AGENT","spokeFirst":true},{"name":"John Doe","phoneNumber":"+15557654321","role":"CUSTOMER","spokeFirst":false}],"properties":{"business_name":"customer-business-name","business_id":"customer-business-id"},"toolInvocations":[{"name":"getDentalAppointments","description":"Get available dental appointments","startOffsetMs":2000,"endOffsetMs":3000,"parameters":{},"result":{"appointments":["cleaning","whitening","rootCanal"]}},{"name":"bookAppointment","description":"Book an appointment for the client","startOffsetMs":7000,"endOffsetMs":7500,"parameters":{"patientName":"John Doe","patientPhone":"+1234567890","appointmentType":{"value":"cleaning","description":"Type of dental appointment","type":"string"}},"result":"Success"}]}},"VapiCallUploadResponse":{"type":"object","properties":{"callId":{"type":"string","description":"ID of the uploaded call"}},"required":["callId"],"description":"Vapi call upload response"},"VapiCallUploadCreate":{"type":"object","properties":{"vapiEndOfCallReportPayload":{"type":"object","additionalProperties":{},"description":"Raw Vapi data forwarded directly from the Vapi end-of-call-report webhook"},"properties":{"type":"object","additionalProperties":{},"description":"Optional metadata (key-value pairs) to include with the call. Useful for filtering and display in call details."},"skipAlreadyImported":{"type":"boolean","default":false,"description":"Skip already imported Vapi calls with the same Vapi call id."}},"required":["vapiEndOfCallReportPayload"],"description":"Vapi call upload payload","example":{"vapiEndOfCallReportPayload":{"call":{"monitor":{"listenUrl":"https://example.com/listen"},"id":"call-123","type":"inboundPhoneCall"},"type":"end-of-call-report","status":"completed","assistant":{"name":"Agent Smith"},"customer":{"number":"+1234567890"},"phoneNumber":{"number":"+0987654321"},"artifact":{"recordingUrl":"https://example.com/recording.mp3","stereoRecordingUrl":"https://example.com/stereo-recording.mp3","messages":[{"role":"system","content":"System message"},{"role":"bot","content":"Hello, I'm Agent Smith"},{"role":"user","content":"Hello"}]},"startedAt":"2025-05-19T23:13:32+08:00","endedAt":"2025-05-19T23:23:32+08:00","endedReason":"customer-ended-call"},"properties":{"business_name":"customer-business-name","business_id":"customer-business-id"}}},"RetellCallUploadResponse":{"type":"object","properties":{"callId":{"type":"string","description":"ID of the uploaded call"}},"required":["callId"],"description":"Retell call upload response"},"RetellCallUploadCreate":{"type":"object","properties":{"retellCallEndedPayload":{"type":"object","additionalProperties":{},"description":"Raw Retell data forwarded directly from the Retell call_ended webhook"},"properties":{"type":"object","additionalProperties":{},"description":"Optional metadata (key-value pairs) to include with the call. Useful for filtering and display in call details."},"skipAlreadyImported":{"type":"boolean","default":false,"description":"Skip already imported Retell calls with the same Retell call id."}},"required":["retellCallEndedPayload"],"description":"Retell call upload payload","example":{"retellCallEndedPayload":{"event":"call_ended","call":{"call_id":"Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6","from_number":"+1234567890","call_type":"web_call","start_timestamp":"1703302407333","agent_id":"oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD","to_number":"+0987654321","direction":"inbound","recording_url":"https://retell.ai/recordings/call-123456.mp3","disconnection_reason":"agent_hangup","end_timestamp":"1703302407333","duration_ms":120000,"transcript_object":[{"role":"agent","content":"Hello, thank you for calling!","words":[{"word":"Hello","start":0.7,"end":1}]},{"role":"user","content":"Hi, I have a question about my account.","words":[{"word":"Hi","start":2.5,"end":2.7}]}],"transcript_with_tool_calls":[{"role":"tool_call_result","tool_call_id":"call-id-123","name":"function_name","arguments":"{ key: \"value\" }"}]}},"properties":{"business_name":"customer-business-name","business_id":"customer-business-id"}}},"CallAnalysisCompletedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"call.analysis.completed","description":"Event name","example":"call.analysis.completed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"callId":{"type":"string","format":"uuid","description":"The call this analysis ran on"},"callAnalysisJobId":{"type":"string","format":"uuid","description":"The completed call analysis job"},"projectId":{"type":"string","format":"uuid","description":"Project the call belongs to"}},"required":["callId","callAnalysisJobId","projectId"]}},"required":["event","version","timestamp","data"],"title":"call.analysis.completed"},"CallAnalysisFailedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"call.analysis.failed","description":"Event name","example":"call.analysis.failed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"callId":{"type":"string","format":"uuid","description":"The call this analysis ran on"},"callAnalysisJobId":{"type":"string","format":"uuid","description":"The completed call analysis job"},"projectId":{"type":"string","format":"uuid","description":"Project the call belongs to"},"errorMessage":{"type":"string","description":"Failure reason if available"}},"required":["callId","callAnalysisJobId","projectId"]}},"required":["event","version","timestamp","data"],"title":"call.analysis.failed"},"CallAnalysisCancelledWebhook":{"type":"object","properties":{"event":{"type":"string","const":"call.analysis.cancelled","description":"Event name","example":"call.analysis.cancelled"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"callId":{"type":"string","format":"uuid","description":"The call this analysis ran on"},"callAnalysisJobId":{"type":"string","format":"uuid","description":"The completed call analysis job"},"projectId":{"type":"string","format":"uuid","description":"Project the call belongs to"}},"required":["callId","callAnalysisJobId","projectId"]}},"required":["event","version","timestamp","data"],"title":"call.analysis.cancelled"},"CallEvaluationCompletedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"call.evaluation.completed","description":"Event name","example":"call.evaluation.completed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"evaluationJobId":{"type":"string","format":"uuid","description":"The completed evaluation job"},"projectId":{"type":"string","format":"uuid","description":"Project the evaluation belongs to"}},"required":["evaluationJobId","projectId"]}},"required":["event","version","timestamp","data"],"title":"call.evaluation.completed"},"CallEvaluationFailedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"call.evaluation.failed","description":"Event name","example":"call.evaluation.failed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"evaluationJobId":{"type":"string","format":"uuid","description":"The completed evaluation job"},"projectId":{"type":"string","format":"uuid","description":"Project the evaluation belongs to"},"errorMessage":{"type":"string","description":"Failure reason if available"}},"required":["evaluationJobId","projectId"]}},"required":["event","version","timestamp","data"],"title":"call.evaluation.failed"},"SimulationRunPlanJobStartedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.run_plan_job.started","description":"Event name","example":"simulation.run_plan_job.started"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"The run plan job this event is about"}},"required":["simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.run_plan_job.started"},"SimulationRunPlanJobCompletedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.run_plan_job.completed","description":"Event name","example":"simulation.run_plan_job.completed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"The run plan job this event is about"}},"required":["simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.run_plan_job.completed"},"SimulationRunPlanJobFailedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.run_plan_job.failed","description":"Event name","example":"simulation.run_plan_job.failed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"The run plan job this event is about"},"status":{"type":"string","description":"Terminal status of the job"},"reason":{"type":"string","description":"Human-readable reason for the failure"}},"required":["simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.run_plan_job.failed"},"SimulationRunPlanJobCancelledWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.run_plan_job.cancelled","description":"Event name","example":"simulation.run_plan_job.cancelled"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"The run plan job this event is about"}},"required":["simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.run_plan_job.cancelled"},"SimulationJobStartedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.job.started","description":"Event name","example":"simulation.job.started"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationJobId":{"type":"string","format":"uuid","description":"The simulation job this event is about"},"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"Parent run plan job"}},"required":["simulationJobId","simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.job.started"},"SimulationJobCompletedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.job.completed","description":"Event name","example":"simulation.job.completed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationJobId":{"type":"string","format":"uuid","description":"The simulation job this event is about"},"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"Parent run plan job"},"callId":{"type":"string","format":"uuid","description":"The call produced by this simulation job, if any"}},"required":["simulationJobId","simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.job.completed"},"SimulationJobFailedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.job.failed","description":"Event name","example":"simulation.job.failed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationJobId":{"type":"string","format":"uuid","description":"The simulation job this event is about"},"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"Parent run plan job"},"status":{"type":"string","description":"Terminal status of the job"},"reason":{"type":"string","description":"Human-readable reason for the failure"}},"required":["simulationJobId","simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.job.failed"},"SimulationJobCancelledWebhook":{"type":"object","properties":{"event":{"type":"string","const":"simulation.job.cancelled","description":"Event name","example":"simulation.job.cancelled"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"simulationJobId":{"type":"string","format":"uuid","description":"The simulation job this event is about"},"simulationRunPlanJobId":{"type":"string","format":"uuid","description":"Parent run plan job"}},"required":["simulationJobId","simulationRunPlanJobId"]}},"required":["event","version","timestamp","data"],"title":"simulation.job.cancelled"},"MetricCollectionJobCompletedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"metric_collection.job.completed","description":"Event name","example":"metric_collection.job.completed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"metricCollectionJobId":{"type":"string","format":"uuid","description":"The metric collection job that completed"},"projectId":{"type":"string","format":"uuid","description":"Project the job ran in"},"callIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Calls included in the job"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Metric policies that matched and triggered the job (empty for user-triggered jobs)"}},"required":["metricCollectionJobId","projectId","callIds","policyIds"]}},"required":["event","version","timestamp","data"],"title":"metric_collection.job.completed"},"MetricCollectionJobFailedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"metric_collection.job.failed","description":"Event name","example":"metric_collection.job.failed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"metricCollectionJobId":{"type":"string","format":"uuid","description":"The metric collection job that completed"},"projectId":{"type":"string","format":"uuid","description":"Project the job ran in"},"callIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Calls included in the job"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Metric policies that matched and triggered the job (empty for user-triggered jobs)"},"errorMessage":{"type":"string","description":"Failure reason if available"}},"required":["metricCollectionJobId","projectId","callIds","policyIds"]}},"required":["event","version","timestamp","data"],"title":"metric_collection.job.failed"},"ChatAnalysisCompletedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"chat.analysis.completed","description":"Event name","example":"chat.analysis.completed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"chatId":{"type":"string","format":"uuid","description":"The chat this analysis ran on"},"projectId":{"type":"string","format":"uuid","description":"Project the chat belongs to"}},"required":["chatId","projectId"]}},"required":["event","version","timestamp","data"],"title":"chat.analysis.completed"},"ChatAnalysisFailedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"chat.analysis.failed","description":"Event name","example":"chat.analysis.failed"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"chatId":{"type":"string","format":"uuid","description":"The chat this analysis ran on"},"projectId":{"type":"string","format":"uuid","description":"Project the chat belongs to"},"errorMessage":{"type":"string","description":"Failure reason if available"}},"required":["chatId","projectId"]}},"required":["event","version","timestamp","data"],"title":"chat.analysis.failed"},"IssueOpenedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"issue.opened","description":"Event name","example":"issue.opened"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"issueId":{"type":"string","format":"uuid","description":"The issue that was opened"},"alertId":{"type":["string","null"],"format":"uuid","description":"Alert configuration that produced the issue, or null for non-alert sources"},"projectId":{"type":"string","format":"uuid","description":"Project the issue belongs to"},"source":{"type":"string","enum":["TREND_ALERT","SINGLE_CALL_ALERT","TRACE_FAILURE","MANUAL","API","AGENT"],"description":"What produced the issue (trend alert, AI clustering, manual triage, API, ...)"},"title":{"type":["string","null"],"description":"Issue title at the time it opened, when available"},"severity":{"type":["string","null"],"enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Issue severity, or null when the producer did not set one"},"groupKey":{"type":["string","null"],"description":"Group key identifying the issue dimension (per the alert config); null for non-alert sources"},"openedAt":{"type":"string","format":"date-time","description":"When the issue was first opened"},"value":{"type":["number","null"],"description":"Triggering metric value, or null when the alert tracks presence/absence"}},"required":["issueId","alertId","projectId","source","title","severity","groupKey","openedAt","value"]}},"required":["event","version","timestamp","data"],"title":"issue.opened"},"IssueResolvedWebhook":{"type":"object","properties":{"event":{"type":"string","const":"issue.resolved","description":"Event name","example":"issue.resolved"},"version":{"type":"string","const":"1.0","description":"Payload schema version","example":"1.0"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the webhook was generated","example":"2026-05-18T09:44:40.971Z"},"data":{"type":"object","properties":{"issueId":{"type":"string","format":"uuid","description":"The issue that was opened"},"alertId":{"type":["string","null"],"format":"uuid","description":"Alert configuration that produced the issue, or null for non-alert sources"},"projectId":{"type":"string","format":"uuid","description":"Project the issue belongs to"},"source":{"type":"string","enum":["TREND_ALERT","SINGLE_CALL_ALERT","TRACE_FAILURE","MANUAL","API","AGENT"],"description":"What produced the issue (trend alert, AI clustering, manual triage, API, ...)"},"title":{"type":["string","null"],"description":"Issue title at the time it opened, when available"},"severity":{"type":["string","null"],"enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Issue severity, or null when the producer did not set one"},"groupKey":{"type":["string","null"],"description":"Group key identifying the issue dimension (per the alert config); null for non-alert sources"},"openedAt":{"type":"string","format":"date-time","description":"When the issue was first opened"},"value":{"type":["number","null"],"description":"Triggering metric value, or null when the alert tracks presence/absence"},"resolvedAt":{"type":"string","format":"date-time","description":"When the issue was resolved"}},"required":["issueId","alertId","projectId","source","title","severity","groupKey","openedAt","value","resolvedAt"]}},"required":["event","version","timestamp","data"],"title":"issue.resolved"}}},"security":[{"Bearer":[]}],"servers":[{"description":"Production","url":"https://api.roark.ai"}],"tags":[{"name":"Agent"},{"name":"Agent Endpoint"},{"name":"Call"},{"name":"Chat"},{"name":"Metric"},{"name":"Metric Policy"},{"name":"Metric Collection Job"},{"name":"Customer Flow"},{"name":"Customer Flow Edge Case"},{"name":"Simulation"},{"name":"Simulation Persona"},{"name":"Simulation Environment"},{"name":"Simulation Scenario"},{"name":"Simulation Run Plan"},{"name":"Simulation Template"},{"name":"Simulation Run Plan Job"},{"name":"Simulation Job"},{"name":"HTTP Request Definition"},{"name":"Webhook"},{"name":"Issue"},{"name":"Knowledge Base"},{"name":"Config"},{"name":"CLI Auth"},{"name":"Call Analysis"},{"name":"Health"}],"webhooks":{"Webhook":{"post":{"operationId":"webhook_event","summary":"Event","description":"Roark POSTs a JSON payload to every endpoint subscribed to one of the events listed below. Every payload uses the same envelope (`event`, `version`, `timestamp`, `data`); the `event` field is the discriminator that selects the matching `data` shape.\n\nAcknowledge with any 2xx response within 10 seconds. Non-2xx responses and timeouts are retried with exponential backoff.\n\n**Events**\n- `call.analysis.completed`\n- `call.analysis.failed`\n- `call.analysis.cancelled`\n- `call.evaluation.completed`\n- `call.evaluation.failed`\n- `simulation.run_plan_job.started`\n- `simulation.run_plan_job.completed`\n- `simulation.run_plan_job.failed`\n- `simulation.run_plan_job.cancelled`\n- `simulation.job.started`\n- `simulation.job.completed`\n- `simulation.job.failed`\n- `simulation.job.cancelled`\n- `metric_collection.job.completed`\n- `metric_collection.job.failed`\n- `chat.analysis.completed`\n- `chat.analysis.failed`\n- `issue.opened`\n- `issue.resolved`","tags":["Webhook"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/CallAnalysisCompletedWebhook"},{"$ref":"#/components/schemas/CallAnalysisFailedWebhook"},{"$ref":"#/components/schemas/CallAnalysisCancelledWebhook"},{"$ref":"#/components/schemas/CallEvaluationCompletedWebhook"},{"$ref":"#/components/schemas/CallEvaluationFailedWebhook"},{"$ref":"#/components/schemas/SimulationRunPlanJobStartedWebhook"},{"$ref":"#/components/schemas/SimulationRunPlanJobCompletedWebhook"},{"$ref":"#/components/schemas/SimulationRunPlanJobFailedWebhook"},{"$ref":"#/components/schemas/SimulationRunPlanJobCancelledWebhook"},{"$ref":"#/components/schemas/SimulationJobStartedWebhook"},{"$ref":"#/components/schemas/SimulationJobCompletedWebhook"},{"$ref":"#/components/schemas/SimulationJobFailedWebhook"},{"$ref":"#/components/schemas/SimulationJobCancelledWebhook"},{"$ref":"#/components/schemas/MetricCollectionJobCompletedWebhook"},{"$ref":"#/components/schemas/MetricCollectionJobFailedWebhook"},{"$ref":"#/components/schemas/ChatAnalysisCompletedWebhook"},{"$ref":"#/components/schemas/ChatAnalysisFailedWebhook"},{"$ref":"#/components/schemas/IssueOpenedWebhook"},{"$ref":"#/components/schemas/IssueResolvedWebhook"}],"discriminator":{"propertyName":"event","mapping":{"call.analysis.completed":"#/components/schemas/CallAnalysisCompletedWebhook","call.analysis.failed":"#/components/schemas/CallAnalysisFailedWebhook","call.analysis.cancelled":"#/components/schemas/CallAnalysisCancelledWebhook","call.evaluation.completed":"#/components/schemas/CallEvaluationCompletedWebhook","call.evaluation.failed":"#/components/schemas/CallEvaluationFailedWebhook","simulation.run_plan_job.started":"#/components/schemas/SimulationRunPlanJobStartedWebhook","simulation.run_plan_job.completed":"#/components/schemas/SimulationRunPlanJobCompletedWebhook","simulation.run_plan_job.failed":"#/components/schemas/SimulationRunPlanJobFailedWebhook","simulation.run_plan_job.cancelled":"#/components/schemas/SimulationRunPlanJobCancelledWebhook","simulation.job.started":"#/components/schemas/SimulationJobStartedWebhook","simulation.job.completed":"#/components/schemas/SimulationJobCompletedWebhook","simulation.job.failed":"#/components/schemas/SimulationJobFailedWebhook","simulation.job.cancelled":"#/components/schemas/SimulationJobCancelledWebhook","metric_collection.job.completed":"#/components/schemas/MetricCollectionJobCompletedWebhook","metric_collection.job.failed":"#/components/schemas/MetricCollectionJobFailedWebhook","chat.analysis.completed":"#/components/schemas/ChatAnalysisCompletedWebhook","chat.analysis.failed":"#/components/schemas/ChatAnalysisFailedWebhook","issue.opened":"#/components/schemas/IssueOpenedWebhook","issue.resolved":"#/components/schemas/IssueResolvedWebhook"}}}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx response is treated as success."}}}}},"paths":{"/health":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HealthResponse"}},"required":["data"]}}},"description":"Health check response"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"},"503":{"description":"Service unavailable — a dependency is unhealthy"}},"operationId":"getHealth","tags":["Health"],"summary":"Get API health status","description":"Returns the health status of the API and its dependencies"}},"/v1/cli/auth/token":{"post":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"token":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"}},"required":["token","name","projectId"]}},"required":["data"]}}},"description":"The minted API key"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1CliAuthToken","tags":["CLI Auth"],"summary":"Exchange a CLI authorization code for an API key","description":"Completes the CLI browser-login flow: verifies the single-use authorization code and its PKCE code_verifier, then mints and returns the approved API key exactly once.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":1},"code_verifier":{"type":"string","minLength":1}},"required":["code","code_verifier"]}}}}}},"/v1/agent/endpoint":{"get":{"responses":{"200":{"description":"List of agent endpoints","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AgentEndpointDetailResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1AgentEndpoint","tags":["Agent Endpoint"],"summary":"List agent endpoints","description":"Returns a paginated list of agent endpoints for the authenticated project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of endpoints to return (default: 20, max: 50)"}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - endpoint ID to start after"}},{"in":"query","name":"agentId","schema":{"type":"string","format":"uuid","description":"Filter by agent ID"}},{"in":"query","name":"searchText","schema":{"type":"string","description":"Search text to filter endpoints"}}]},"post":{"responses":{"201":{"description":"The created agent endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AgentEndpointDetailResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1AgentEndpoint","tags":["Agent Endpoint"],"summary":"Create a new agent endpoint","description":"Creates a new agent endpoint for the authenticated project.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAgentEndpointInput"}}}}}},"/v1/agent/endpoint/{endpointId}":{"get":{"responses":{"200":{"description":"The requested agent endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AgentEndpointDetailResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1AgentEndpointByEndpointId","tags":["Agent Endpoint"],"summary":"Get agent endpoint by ID","description":"Returns a specific agent endpoint by its ID.","parameters":[{"name":"endpointId","in":"path","required":true,"description":"The ID of the agent endpoint to retrieve","schema":{"type":"string"}}]},"put":{"responses":{"200":{"description":"The updated agent endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AgentEndpointDetailResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1AgentEndpointByEndpointId","tags":["Agent Endpoint"],"summary":"Update an agent endpoint","description":"Updates an existing agent endpoint by its ID. Only environment and outboundDialType can be modified.","parameters":[{"name":"endpointId","in":"path","required":true,"description":"The ID of the agent endpoint to update","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAgentEndpointInput"}}}}}},"/v1/agent/{agentId}/prompts":{"get":{"responses":{"200":{"description":"The agent's prompt lineages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAgentPromptsResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1AgentByAgentIdPrompts","tags":["Agent"],"summary":"List an agent's prompts","description":"Returns the agent's prompt lineages. Each lineage is an independent version history, labelled by its `source` (USER, API, CONFIG, or a provider integration). `prompt` is the current content.","parameters":[{"in":"path","name":"agentId","schema":{"type":"string","format":"uuid"},"required":true}]},"put":{"responses":{"200":{"description":"The prompt was set (or already matched the current version).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SetAgentPromptResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1AgentByAgentIdPrompts","tags":["Agent"],"summary":"Set an agent's prompt","description":"Sets the agent's API-managed prompt. This is its own version history (`source: API_MANAGED`), separate from prompts observed on calls, edited in the app, or managed by config-as-code. Setting the same content twice is a no-op (no new version). Roark does not run your agent and no metric reads this prompt: it is stored and versioned for your reference.","parameters":[{"in":"path","name":"agentId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetAgentPromptInput"}}}}}},"/v1/agent/{agentId}/prompts/{promptId}/versions":{"get":{"responses":{"200":{"description":"The version history of the prompt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAgentPromptVersionsResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1AgentByAgentIdPromptsByPromptIdVersions","tags":["Agent"],"summary":"List a prompt's versions","description":"Returns the full version history of a single prompt lineage, newest first.","parameters":[{"in":"path","name":"agentId","schema":{"type":"string","format":"uuid"},"required":true},{"in":"path","name":"promptId","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/agent":{"get":{"responses":{"200":{"description":"List of agents","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Agent","tags":["Agent"],"summary":"List agents","description":"Returns a paginated list of agents for the authenticated project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"in":"query","name":"after","schema":{"type":"string"}},{"in":"query","name":"searchText","schema":{"type":"string"}}]},"post":{"responses":{"201":{"description":"The created agent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Agent","tags":["Agent"],"summary":"Create a new agent","description":"Creates a new agent for the authenticated project.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"}},"required":["name"],"title":"CreateAgentInput","description":"Input for creating a new agent"}}}}}},"/v1/agent/{agentId}":{"get":{"responses":{"200":{"description":"The requested agent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1AgentByAgentId","tags":["Agent"],"summary":"Get agent by ID","description":"Returns a specific agent by its ID.","parameters":[{"name":"agentId","in":"path","required":true,"description":"The ID of the agent to retrieve","schema":{"type":"string"}}]},"put":{"responses":{"200":{"description":"The updated agent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the agent"},"name":{"type":"string","description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"},"customId":{"type":["string","null"],"description":"Custom identifier for the agent"},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format"},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format"}},"required":["id","name","description","customId","createdAt","updatedAt"]}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1AgentByAgentId","tags":["Agent"],"summary":"Update an agent","description":"Updates an existing agent by its ID.","parameters":[{"name":"agentId","in":"path","required":true,"description":"The ID of the agent to update","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Name of the agent"},"description":{"type":["string","null"],"description":"Description of the agent"}},"title":"UpdateAgentInput","description":"Input for updating an existing agent"}}}}},"delete":{"responses":{"200":{"description":"The agent was deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the deleted agent"},"deleted":{"type":"boolean","const":true,"description":"Always true when the agent was successfully deleted"}},"required":["id","deleted"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Conflict error"},"example":{"type":"conflict","code":"resource_in_use","message":"The resource is in use and cannot be deleted"}}},"description":"Conflict"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1AgentByAgentId","tags":["Agent"],"summary":"Delete an agent","description":"Soft-deletes an agent by its ID. The agent is hidden from all reads and stops being attributed to new calls, but its record and history are retained. Fails with 409 if the agent is still referenced by simulation run plans: cancel those run plans first. Note: if the agent syncs from a provider integration, also exclude it in the integration settings (or delete the integration) so its calls stop reaching Roark.","parameters":[{"name":"agentId","in":"path","required":true,"description":"The ID of the agent to delete","schema":{"type":"string"}}]}},"/v1/call":{"get":{"responses":{"200":{"description":"List of calls","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the call","example":"550e8400-e29b-41d4-a716-446655440000"},"projectId":{"type":"string","format":"uuid","description":"ID of the project this call belongs to","example":"660e8400-e29b-41d4-a716-446655440001"},"title":{"type":["string","null"],"description":"Auto-generated title for the call based on content","example":"Customer support inquiry"},"summary":{"type":["string","null"],"description":"Auto-generated summary of the call conversation","example":"Customer inquired about billing and payment options"},"status":{"type":["string","null"],"enum":["RINGING","IN_PROGRESS","ENDED"],"description":"Current status of the call","example":"ENDED"},"callDirection":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the call (inbound or outbound)","example":"INBOUND"},"startedAt":{"type":"string","description":"Timestamp when the call started","example":"2024-01-15T10:00:00Z"},"endedAt":{"type":["string","null"],"description":"Timestamp when the call ended","example":"2024-01-15T10:30:00Z"},"durationMs":{"type":["number","null"],"description":"Duration of the call in milliseconds","example":1800000},"endedStatus":{"type":["string","null"],"enum":["PARTICIPANTS_DID_NOT_SPEAK","AGENT_DID_NOT_ANSWER","AGENT_DID_NOT_SPEAK","AGENT_STOPPED_SPEAKING","AGENT_ENDED_CALL","AGENT_TRANSFERRED_CALL","AGENT_BUSY","AGENT_ERROR","CUSTOMER_ENDED_CALL","VOICE_MAIL_REACHED","SILENCE_TIME_OUT","PHONE_CALL_PROVIDER_CONNECTION_ERROR","CUSTOMER_DID_NOT_ANSWER","CUSTOMER_DID_NOT_SPEAK","CUSTOMER_STOPPED_SPEAKING","CUSTOMER_BUSY","DIAL_ERROR","MAX_DURATION_REACHED","UNKNOWN"],"description":"Status indicating how the call ended","example":"AGENT_ENDED_CALL"},"recordingUrl":{"type":["string","null"],"description":"Pre-signed URL to the call recording (expires in 1 hour)","example":"https://s3.amazonaws.com/bucket/recording.mp3?..."},"recordingUrlAccess":{"type":"string","enum":["AVAILABLE","NOT_AVAILABLE","RESTRICTED"],"description":"Indicates the status of `recordingUrl`. `AVAILABLE`: signed URL returned. `NOT_AVAILABLE`: no recording on file yet (e.g. still processing). `RESTRICTED`: the calling API key does not have the `recording:read` permission and the URL has been withheld.","example":"AVAILABLE"},"simulationJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation job if this call was generated by a simulation","example":"880e8400-e29b-41d4-a716-446655440003"},"supersededByCallId":{"type":["string","null"],"format":"uuid","description":"ID of the call that superseded this one (if applicable)","example":"990e8400-e29b-41d4-a716-446655440004"},"externalId":{"type":["string","null"],"description":"Caller-supplied correlation ID echoed back from the create request, if any was provided","example":"session-abc-123"},"agents":{"type":["array","null"],"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"environment":{"type":"string"},"phoneNumberE164":{"type":["string","null"]}},"required":["id","environment"]}},"required":["id"]},"description":"Agent information","example":[{"id":"550e8400-e29b-41d4-a716-446655440000","endpoint":{"id":"550e8400-e29b-41d4-a716-446655440000","environment":"Production","phoneNumberE164":"+1234567890"}}]},"customers":{"type":["array","null"],"items":{"type":"object","properties":{"phoneNumberE164":{"type":["string","null"]},"label":{"type":["string","null"]}}},"description":"Customer information","example":[{"phoneNumberE164":"+1234567891","label":"customer-01"}]},"createdAt":{"type":["string","null"],"description":"Timestamp when the call record was created","example":"2024-01-15T10:31:00Z"},"updatedAt":{"type":["string","null"],"description":"Timestamp when the call record was last updated","example":"2024-01-15T10:31:00Z"},"properties":{"type":["object","null"],"additionalProperties":{},"description":"Custom properties associated with the call","example":{"ticketId":"TCK-123","department":"sales"}},"policyIds":{"type":["array","null"],"items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that have been applied to this call","example":["550e8400-e29b-41d4-a716-446655440000"]}},"required":["id","projectId","callDirection","startedAt","recordingUrlAccess"],"title":"CallResponse","description":"Response containing call information"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Call","tags":["Call"],"summary":"List calls","description":"Returns a paginated list of calls for the authenticated project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of calls to return (default: 20, max: 100)","example":20}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - use the nextCursor value from a previous response","example":"eyJzb3J0VmFsdWUiOiIyMDI1LTAxLTE1VDEwOjAwOjAwLjAwMDAwMFoiLCJpZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCJ9"}},{"in":"query","name":"sortBy","schema":{"type":"string","enum":["createdAt","startedAt","endedAt","duration","title","status"],"default":"createdAt","description":"Field to sort by (default: createdAt)","example":"createdAt"}},{"in":"query","name":"sortDirection","schema":{"type":"string","enum":["asc","desc"],"default":"desc","description":"Sort direction (default: desc)","example":"desc"}},{"in":"query","name":"status","schema":{"type":"string","enum":["RINGING","IN_PROGRESS","ENDED"],"description":"Filter by call status","example":"ENDED"}},{"in":"query","name":"searchText","schema":{"type":"string","description":"Search text to filter calls by title, summary, or transcript","example":"billing inquiry"}},{"in":"query","name":"simulationRunPlanJobId","schema":{"type":"string","format":"uuid","description":"Filter by simulation run plan job ID to get all calls from a specific simulation batch","example":"550e8400-e29b-41d4-a716-446655440000"}}]},"post":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the call","example":"550e8400-e29b-41d4-a716-446655440000"},"projectId":{"type":"string","format":"uuid","description":"ID of the project this call belongs to","example":"660e8400-e29b-41d4-a716-446655440001"},"status":{"type":["string","null"],"enum":["RINGING","IN_PROGRESS","ENDED"]},"callDirection":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the call (inbound or outbound)","example":"INBOUND"},"startedAt":{"type":"string","description":"Timestamp when the call started","example":"2024-01-15T10:00:00Z"},"agents":{"type":["array","null"],"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"environment":{"type":"string"},"phoneNumberE164":{"type":["string","null"]}},"required":["id","environment"]}},"required":["id"]}},"customers":{"type":["array","null"],"items":{"type":"object","properties":{"phoneNumberE164":{"type":["string","null"]},"label":{"type":["string","null"]}}}},"createdAt":{"type":["string","null"]},"externalId":{"type":["string","null"]}},"required":["id","projectId","status","callDirection","startedAt","agents","customers","createdAt","externalId"],"title":"CallCreateResponse","description":"Response after creating a call"}},"required":["data"]}}},"description":"Call created successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Call","tags":["Call"],"summary":"Create a call","description":"Create a new call with recording, transcript, agents, and customers","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallCreate"}}}}}},"/v1/call/{callId}":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the call","example":"550e8400-e29b-41d4-a716-446655440000"},"projectId":{"type":"string","format":"uuid","description":"ID of the project this call belongs to","example":"660e8400-e29b-41d4-a716-446655440001"},"title":{"type":["string","null"],"description":"Auto-generated title for the call based on content","example":"Customer support inquiry"},"summary":{"type":["string","null"],"description":"Auto-generated summary of the call conversation","example":"Customer inquired about billing and payment options"},"status":{"type":["string","null"],"enum":["RINGING","IN_PROGRESS","ENDED"],"description":"Current status of the call","example":"ENDED"},"callDirection":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Direction of the call (inbound or outbound)","example":"INBOUND"},"startedAt":{"type":"string","description":"Timestamp when the call started","example":"2024-01-15T10:00:00Z"},"endedAt":{"type":["string","null"],"description":"Timestamp when the call ended","example":"2024-01-15T10:30:00Z"},"durationMs":{"type":["number","null"],"description":"Duration of the call in milliseconds","example":1800000},"endedStatus":{"type":["string","null"],"enum":["PARTICIPANTS_DID_NOT_SPEAK","AGENT_DID_NOT_ANSWER","AGENT_DID_NOT_SPEAK","AGENT_STOPPED_SPEAKING","AGENT_ENDED_CALL","AGENT_TRANSFERRED_CALL","AGENT_BUSY","AGENT_ERROR","CUSTOMER_ENDED_CALL","VOICE_MAIL_REACHED","SILENCE_TIME_OUT","PHONE_CALL_PROVIDER_CONNECTION_ERROR","CUSTOMER_DID_NOT_ANSWER","CUSTOMER_DID_NOT_SPEAK","CUSTOMER_STOPPED_SPEAKING","CUSTOMER_BUSY","DIAL_ERROR","MAX_DURATION_REACHED","UNKNOWN"],"description":"Status indicating how the call ended","example":"AGENT_ENDED_CALL"},"recordingUrl":{"type":["string","null"],"description":"Pre-signed URL to the call recording (expires in 1 hour)","example":"https://s3.amazonaws.com/bucket/recording.mp3?..."},"recordingUrlAccess":{"type":"string","enum":["AVAILABLE","NOT_AVAILABLE","RESTRICTED"],"description":"Indicates the status of `recordingUrl`. `AVAILABLE`: signed URL returned. `NOT_AVAILABLE`: no recording on file yet (e.g. still processing). `RESTRICTED`: the calling API key does not have the `recording:read` permission and the URL has been withheld.","example":"AVAILABLE"},"simulationJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation job if this call was generated by a simulation","example":"880e8400-e29b-41d4-a716-446655440003"},"supersededByCallId":{"type":["string","null"],"format":"uuid","description":"ID of the call that superseded this one (if applicable)","example":"990e8400-e29b-41d4-a716-446655440004"},"externalId":{"type":["string","null"],"description":"Caller-supplied correlation ID echoed back from the create request, if any was provided","example":"session-abc-123"},"agents":{"type":["array","null"],"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"environment":{"type":"string"},"phoneNumberE164":{"type":["string","null"]}},"required":["id","environment"]}},"required":["id"]},"description":"Agent information","example":[{"id":"550e8400-e29b-41d4-a716-446655440000","endpoint":{"id":"550e8400-e29b-41d4-a716-446655440000","environment":"Production","phoneNumberE164":"+1234567890"}}]},"customers":{"type":["array","null"],"items":{"type":"object","properties":{"phoneNumberE164":{"type":["string","null"]},"label":{"type":["string","null"]}}},"description":"Customer information","example":[{"phoneNumberE164":"+1234567891","label":"customer-01"}]},"createdAt":{"type":["string","null"],"description":"Timestamp when the call record was created","example":"2024-01-15T10:31:00Z"},"updatedAt":{"type":["string","null"],"description":"Timestamp when the call record was last updated","example":"2024-01-15T10:31:00Z"},"properties":{"type":["object","null"],"additionalProperties":{},"description":"Custom properties associated with the call","example":{"ticketId":"TCK-123","department":"sales"}},"policyIds":{"type":["array","null"],"items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that have been applied to this call","example":["550e8400-e29b-41d4-a716-446655440000"]}},"required":["id","projectId","callDirection","startedAt","recordingUrlAccess"],"title":"CallResponse","description":"Response containing call information"}},"required":["data"]}}},"description":"Call retrieved successfully"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Call not found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1CallByCallId","tags":["Call"],"summary":"Get a call by ID","description":"Retrieve an existing call by its unique identifier","parameters":[{"in":"path","name":"callId","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/call/{callId}/sentiment-run":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","description":"Status of the sentiment run"},"averageSentiment":{"type":"number","description":"Average sentiment score between 0-1 of the call"},"averageCategoricalSentiment":{"type":"string","description":"NEUTRAL / NEGATIVE / POSITIVE"},"commonEmotion":{"type":"string","description":"Common emotion of the call"}},"required":["status"],"description":"Sentiment run response payload"}},"required":["data"]}}},"description":"Sentiment analysis for a specific call"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1CallByCallIdSentiment-run","tags":["Call"],"summary":"List call sentiment runs","description":"Fetch detailed sentiment analysis results for a specific call, including emotional tone, key phrases, and sentiment scores.","parameters":[{"in":"path","name":"callId","schema":{"type":"string","format":"uuid","description":"ID of the call to fetch sentiment run for"},"required":true}]}},"/v1/call/{callId}/metrics":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"metricDefinitionId":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"values":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"}],"description":"The metric value (type depends on outputType). Present only on SUCCESS rows; omitted for NOT_APPLICABLE / DATA_MISSING / ERROR."},"callId":{"type":"string","format":"uuid","description":"ID of the call this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"chatId":{"type":"string","format":"uuid","description":"ID of the chat this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"captureStatus":{"type":"string","enum":["SUCCESS","NOT_APPLICABLE","DATA_MISSING","ERROR"],"description":"Result state of this metric computation. SUCCESS carries a real `value`; NOT_APPLICABLE / DATA_MISSING / ERROR do not (the `value` field is omitted). Non-SUCCESS rows only appear when the request includes ?status=all."},"errorMessage":{"type":"string","description":"Error detail when captureStatus is ERROR — e.g. provider down, LLM timeout. Undefined for other statuses."},"context":{"type":"string","enum":["CALL","SEGMENT","SEGMENT_RANGE"],"description":"Context level: CALL (entire conversation), SEGMENT (single segment), SEGMENT_RANGE (between/across segments)"},"participantRole":{"type":"string","enum":["agent","customer"],"description":"Role of participant (only for PER_PARTICIPANT metrics)"},"valueReasoning":{"type":"string","description":"Explanation for the metric value (especially useful for AI-computed metrics)"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence score (0-1) for the computed value. Defaults to 1.0 for deterministic metrics. Omitted on non-SUCCESS rows."},"computedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the metric was computed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that triggered this metric computation"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Segment information (for SEGMENT context metrics)"},"fromSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Starting segment information (for SEGMENT_RANGE context metrics)"},"toSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Ending segment information (for SEGMENT_RANGE context metrics)"}},"required":["captureStatus","context","computedAt"],"title":"Standard metric value","description":"A metric value entry. Applies to every metric."},{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"}],"description":"The metric value (type depends on outputType). Present only on SUCCESS rows; omitted for NOT_APPLICABLE / DATA_MISSING / ERROR."},"callId":{"type":"string","format":"uuid","description":"ID of the call this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"chatId":{"type":"string","format":"uuid","description":"ID of the chat this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"captureStatus":{"type":"string","enum":["SUCCESS","NOT_APPLICABLE","DATA_MISSING","ERROR"],"description":"Result state of this metric computation. SUCCESS carries a real `value`; NOT_APPLICABLE / DATA_MISSING / ERROR do not (the `value` field is omitted). Non-SUCCESS rows only appear when the request includes ?status=all."},"errorMessage":{"type":"string","description":"Error detail when captureStatus is ERROR — e.g. provider down, LLM timeout. Undefined for other statuses."},"context":{"type":"string","enum":["CALL","SEGMENT","SEGMENT_RANGE"],"description":"Context level: CALL (entire conversation), SEGMENT (single segment), SEGMENT_RANGE (between/across segments)"},"participantRole":{"type":"string","enum":["agent","customer"],"description":"Role of participant (only for PER_PARTICIPANT metrics)"},"valueReasoning":{"type":"string","description":"Explanation for the metric value (especially useful for AI-computed metrics)"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence score (0-1) for the computed value. Defaults to 1.0 for deterministic metrics. Omitted on non-SUCCESS rows."},"computedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the metric was computed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that triggered this metric computation"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Segment information (for SEGMENT context metrics)"},"fromSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Starting segment information (for SEGMENT_RANGE context metrics)"},"toSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Ending segment information (for SEGMENT_RANGE context metrics)"},"propertyVerdicts":{"type":"array","items":{"type":"object","properties":{"propertyName":{"type":"string","description":"The call property checked, as sent at ingest"},"expectedValue":{"type":"string","description":"The value supplied at ingest, frozen at scoring time"},"observedValue":{"type":"string","description":"What the transcript said instead. Only present when verdict is MISMATCH."},"verdict":{"type":"string","enum":["MATCH","MISMATCH","TRANSCRIPTION_ERROR","NOT_MENTIONED"],"description":"How this property resolved against the transcript. NOT_MENTIONED means the subject never came up and is not a mismatch."},"reasoning":{"type":"string","description":"Judge reasoning for this verdict"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"The transcript segment this property was referred to in: the conflicting value for MISMATCH, the confirming reference for MATCH. Omitted for NOT_MENTIONED and when the verdict could not be anchored."}},"required":["propertyName","expectedValue","verdict"]},"description":"Per-property verdicts for the Property Mismatch metric, in the order the properties were checked. Omitted for every other metric."}},"required":["captureStatus","context","computedAt"],"title":"Property verification metric value","description":"Returned for the Property Mismatch metric (`property_transcript_mismatch`): the standard entry plus the per-property verdict breakdown."}]},"description":"Array of metric values (multiple for PER_PARTICIPANT metrics, or multiple segments/turns)"}},"required":["metricDefinitionId","slug","metricId","name","description","type","scope","values"],"description":"Metric data grouped by metric definition"},"description":"Conversation metrics response payload grouped by metric definition"}},"required":["data"]}}},"description":"Call-level metrics for a specific call"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1CallByCallIdMetrics","tags":["Call"],"summary":"List call metrics","description":"Fetch all call-level metrics for a specific call, including both system-generated and custom metrics. Only returns rows from the **latest** metric-collection job per metric — if the same metric has been recomputed, prior runs are excluded and remain in the metric history. By default returns only successfully computed metrics; pass `?status=all` to also include rows that resolved as NOT_APPLICABLE / DATA_MISSING / ERROR (the `value` field is omitted on those entries — check `captureStatus`).","parameters":[{"in":"query","name":"flatten","schema":{"type":"string","description":"Whether to return a flat list instead of grouped by metric definition (default: false)"}},{"in":"query","name":"status","schema":{"type":"string","enum":["success","all"],"default":"success","description":"Filter metrics by capture status. `success` (default) returns only successfully computed metrics — backwards-compatible with the historical behavior. `all` also returns NOT_APPLICABLE / DATA_MISSING / ERROR rows (with `value` omitted), so clients can distinguish \"still computing\" from \"computed but no value\" and exit retry loops correctly."}},{"schema":{"type":"string"},"in":"path","name":"callId","required":true}]}},"/v1/call/{callId}/transcript":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"transcriptionSource":{"type":["string","null"],"enum":["ROARK_POST_CALL","SIMULATION_AGENT_REALTIME","CUSTOMER_AGENT_REALTIME"],"description":"The transcription source used for this transcript. Null if no transcript is available."},"participants":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"AGENT"},"agentId":{"type":["string","null"],"format":"uuid","description":"ID of the agent entity"}},"required":["id","type","agentId"],"description":"An agent participant"},{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"CUSTOMER"},"customerId":{"type":["string","null"],"format":"uuid","description":"ID of the conversation customer record"}},"required":["id","type","customerId"],"description":"A customer participant"},{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"SIMULATED_CUSTOMER"},"customerId":{"type":["string","null"],"format":"uuid","description":"ID of the conversation customer record"}},"required":["id","type","customerId"],"description":"A simulated customer participant"},{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"BACKGROUND_SPEAKER"}},"required":["id","type"],"description":"A background speaker participant"}],"description":"A participant in the conversation"},"description":"All participants in this transcript, referenced by participantId on each entry"},"entries":{"type":"array","items":{"type":"object","properties":{"participantId":{"type":["string","null"],"format":"uuid","description":"ID of the conversation participant who produced this entry. References participants[].id."},"role":{"type":["string","null"],"enum":["AGENT","CUSTOMER"],"description":"Convenience role derived from participant type"},"text":{"type":"string","description":"Transcript text for this entry"},"startOffsetMs":{"type":"integer","minimum":0,"description":"Start time offset in milliseconds from the start of the conversation"},"endOffsetMs":{"type":"integer","minimum":0,"description":"End time offset in milliseconds from the start of the conversation"}},"required":["participantId","role","text","startOffsetMs","endOffsetMs"],"description":"A single transcript entry"},"description":"Ordered list of transcript entries from the call"}},"required":["transcriptionSource","participants","entries"],"description":"Call transcript response"}},"required":["data"]}}},"description":"Transcript for the specified call"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1CallByCallIdTranscript","tags":["Call"],"summary":"Get call transcript","description":"Fetch the full transcript for a specific call. Optionally specify a transcription source; otherwise the best available source is used automatically.","parameters":[{"in":"query","name":"source","schema":{"type":"string","enum":["ROARK_POST_CALL","SIMULATION_AGENT_REALTIME","CUSTOMER_AGENT_REALTIME"],"description":"Transcription source to fetch. When omitted, uses the preferred source based on availability: CUSTOMER_AGENT_REALTIME > SIMULATION_AGENT_REALTIME > ROARK_POST_CALL"}},{"schema":{"type":"string"},"in":"path","name":"callId","required":true}]}},"/v1/call/{callId}/tool-invocations":{"post":{"responses":{"200":{"description":"Tool invocations attached to the call","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppendToolInvocationsResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1CallByCallIdTool-invocations","tags":["Call"],"summary":"Append tool invocations to a call","description":"Attach tool invocations that fired during a call to an already-existing call, asynchronously after the call was created. Use this when the tool-call data becomes available later than the call itself (e.g. a Roark simulation, or a call submitted via POST /v1/call before its tools were ready). Writes are idempotent: re-sending an invocation already present on the call (same tool name and timing) is skipped, so retries converge instead of double-counting. Optionally pass `metrics` to (re)score metrics over the newly attached tools, which triggers a billed metric collection job and requires the `metric:create` permission.","parameters":[{"in":"path","name":"callId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendToolInvocationsRequest"}}}}}},"/v1/chat":{"get":{"responses":{"200":{"description":"List of chats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the chat","example":"550e8400-e29b-41d4-a716-446655440000"},"projectId":{"type":"string","format":"uuid","description":"ID of the project this chat belongs to","example":"660e8400-e29b-41d4-a716-446655440001"},"organizationId":{"type":"string","format":"uuid","description":"ID of the organization this chat belongs to","example":"770e8400-e29b-41d4-a716-446655440002"},"title":{"type":["string","null"],"description":"Auto-generated title for the chat based on content","example":"Account assistance request"},"summary":{"type":["string","null"],"description":"Auto-generated summary of the chat conversation","example":"Customer inquired about account balance and recent transactions"},"startTimestamp":{"type":"string","description":"Timestamp when the chat started","example":"2024-01-15T10:00:00Z"},"endTimestamp":{"type":"string","description":"Timestamp when the chat ended","example":"2024-01-15T10:30:00Z"},"durationMs":{"type":"number","description":"Duration of the chat in milliseconds","example":1800000},"createdAt":{"type":["string","null"],"description":"Timestamp when the chat record was created","example":"2024-01-15T10:31:00Z"},"updatedAt":{"type":["string","null"],"description":"Timestamp when the chat record was last updated","example":"2024-01-15T10:31:00Z"},"simulationJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation job if this chat was generated by a simulation","example":"880e8400-e29b-41d4-a716-446655440003"},"simulationRunPlanJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation run plan job that this chat belongs to (if applicable)","example":"990e8400-e29b-41d4-a716-446655440004"},"agents":{"type":["array","null"],"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Agent information","example":[{"id":"550e8400-e29b-41d4-a716-446655440000"}]},"customers":{"type":["array","null"],"items":{"type":"object","properties":{"phoneNumberE164":{"type":["string","null"]},"label":{"type":["string","null"]}}},"description":"Customer information","example":[{"phoneNumberE164":null,"label":"web-visitor-abc123"}]},"properties":{"type":["object","null"],"additionalProperties":{},"description":"Custom properties associated with the chat","example":{"source":"web","region":"US"}},"policyIds":{"type":["array","null"],"items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that have been applied to this chat","example":["550e8400-e29b-41d4-a716-446655440000"]},"externalId":{"type":["string","null"],"description":"Caller-supplied correlation ID echoed back from the create request, if any was provided","example":"session-abc-123"}},"required":["id","projectId","organizationId","startTimestamp","endTimestamp","durationMs"],"title":"ChatResponse","description":"Response containing the chat information"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Chat","tags":["Chat"],"summary":"List chats","description":"Returns a paginated list of chats for the authenticated project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of chats to return (default: 20, max: 100)","example":20}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - use the nextCursor value from a previous response","example":"eyJzb3J0VmFsdWUiOiIyMDI1LTAxLTE1VDEwOjAwOjAwLjAwMDAwMFoiLCJpZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCJ9"}},{"in":"query","name":"sortBy","schema":{"type":"string","enum":["createdAt","startTimestamp","endTimestamp","duration","title"],"default":"createdAt","description":"Field to sort by (default: createdAt)","example":"createdAt"}},{"in":"query","name":"sortDirection","schema":{"type":"string","enum":["asc","desc"],"default":"desc","description":"Sort direction (default: desc)","example":"desc"}},{"in":"query","name":"searchText","schema":{"type":"string","description":"Search text to filter chats by id, title, summary, message text, or note content","example":"account balance"}},{"in":"query","name":"simulationRunPlanJobId","schema":{"type":"string","format":"uuid","description":"Filter by simulation run plan job ID to get all chats from a specific simulation batch","example":"550e8400-e29b-41d4-a716-446655440000"}}]},"post":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the chat","example":"550e8400-e29b-41d4-a716-446655440000"},"projectId":{"type":"string","format":"uuid","description":"ID of the project this chat belongs to","example":"660e8400-e29b-41d4-a716-446655440001"},"organizationId":{"type":"string","format":"uuid","description":"ID of the organization this chat belongs to","example":"770e8400-e29b-41d4-a716-446655440002"},"title":{"type":["string","null"],"description":"Auto-generated title for the chat based on content","example":"Account assistance request"},"summary":{"type":["string","null"],"description":"Auto-generated summary of the chat conversation","example":"Customer inquired about account balance and recent transactions"},"startTimestamp":{"type":"string","description":"Timestamp when the chat started","example":"2024-01-15T10:00:00Z"},"endTimestamp":{"type":"string","description":"Timestamp when the chat ended","example":"2024-01-15T10:30:00Z"},"durationMs":{"type":"number","description":"Duration of the chat in milliseconds","example":1800000},"createdAt":{"type":["string","null"],"description":"Timestamp when the chat record was created","example":"2024-01-15T10:31:00Z"},"updatedAt":{"type":["string","null"],"description":"Timestamp when the chat record was last updated","example":"2024-01-15T10:31:00Z"},"simulationJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation job if this chat was generated by a simulation","example":"880e8400-e29b-41d4-a716-446655440003"},"simulationRunPlanJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation run plan job that this chat belongs to (if applicable)","example":"990e8400-e29b-41d4-a716-446655440004"},"agents":{"type":["array","null"],"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Agent information","example":[{"id":"550e8400-e29b-41d4-a716-446655440000"}]},"customers":{"type":["array","null"],"items":{"type":"object","properties":{"phoneNumberE164":{"type":["string","null"]},"label":{"type":["string","null"]}}},"description":"Customer information","example":[{"phoneNumberE164":null,"label":"web-visitor-abc123"}]},"properties":{"type":["object","null"],"additionalProperties":{},"description":"Custom properties associated with the chat","example":{"source":"web","region":"US"}},"policyIds":{"type":["array","null"],"items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that have been applied to this chat","example":["550e8400-e29b-41d4-a716-446655440000"]},"externalId":{"type":["string","null"],"description":"Caller-supplied correlation ID echoed back from the create request, if any was provided","example":"session-abc-123"}},"required":["id","projectId","organizationId","startTimestamp","endTimestamp","durationMs"],"title":"ChatResponse","description":"Response containing the chat information"}},"required":["data"]}}},"description":"Chat created successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad request - validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Chat","tags":["Chat"],"summary":"Create a chat","description":"Create a new chat with segments (messages and tool invocations)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCreate"}}}}}},"/v1/chat/{id}":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the chat","example":"550e8400-e29b-41d4-a716-446655440000"},"projectId":{"type":"string","format":"uuid","description":"ID of the project this chat belongs to","example":"660e8400-e29b-41d4-a716-446655440001"},"organizationId":{"type":"string","format":"uuid","description":"ID of the organization this chat belongs to","example":"770e8400-e29b-41d4-a716-446655440002"},"title":{"type":["string","null"],"description":"Auto-generated title for the chat based on content","example":"Account assistance request"},"summary":{"type":["string","null"],"description":"Auto-generated summary of the chat conversation","example":"Customer inquired about account balance and recent transactions"},"startTimestamp":{"type":"string","description":"Timestamp when the chat started","example":"2024-01-15T10:00:00Z"},"endTimestamp":{"type":"string","description":"Timestamp when the chat ended","example":"2024-01-15T10:30:00Z"},"durationMs":{"type":"number","description":"Duration of the chat in milliseconds","example":1800000},"createdAt":{"type":["string","null"],"description":"Timestamp when the chat record was created","example":"2024-01-15T10:31:00Z"},"updatedAt":{"type":["string","null"],"description":"Timestamp when the chat record was last updated","example":"2024-01-15T10:31:00Z"},"simulationJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation job if this chat was generated by a simulation","example":"880e8400-e29b-41d4-a716-446655440003"},"simulationRunPlanJobId":{"type":["string","null"],"format":"uuid","description":"ID of the simulation run plan job that this chat belongs to (if applicable)","example":"990e8400-e29b-41d4-a716-446655440004"},"agents":{"type":["array","null"],"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Agent information","example":[{"id":"550e8400-e29b-41d4-a716-446655440000"}]},"customers":{"type":["array","null"],"items":{"type":"object","properties":{"phoneNumberE164":{"type":["string","null"]},"label":{"type":["string","null"]}}},"description":"Customer information","example":[{"phoneNumberE164":null,"label":"web-visitor-abc123"}]},"properties":{"type":["object","null"],"additionalProperties":{},"description":"Custom properties associated with the chat","example":{"source":"web","region":"US"}},"policyIds":{"type":["array","null"],"items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that have been applied to this chat","example":["550e8400-e29b-41d4-a716-446655440000"]},"externalId":{"type":["string","null"],"description":"Caller-supplied correlation ID echoed back from the create request, if any was provided","example":"session-abc-123"}},"required":["id","projectId","organizationId","startTimestamp","endTimestamp","durationMs"],"title":"ChatResponse","description":"Response containing the chat information"}},"required":["data"]}}},"description":"Chat retrieved successfully"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Chat not found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1ChatById","tags":["Chat"],"summary":"Get a chat by ID","description":"Retrieve an existing chat by its unique identifier","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/chat/{id}/transcript":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"participants":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"AGENT"},"agentId":{"type":["string","null"],"format":"uuid","description":"ID of the agent entity"}},"required":["id","type","agentId"],"description":"An agent participant"},{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"CUSTOMER"},"customerId":{"type":["string","null"],"format":"uuid","description":"ID of the conversation customer record"}},"required":["id","type","customerId"],"description":"A customer participant"},{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"SIMULATED_CUSTOMER"},"customerId":{"type":["string","null"],"format":"uuid","description":"ID of the conversation customer record"}},"required":["id","type","customerId"],"description":"A simulated customer participant"},{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Conversation participant ID"},"type":{"type":"string","const":"BACKGROUND_SPEAKER"}},"required":["id","type"],"description":"A background speaker participant"}],"description":"A participant in the conversation"},"description":"All participants in this transcript, referenced by participantId on each entry"},"entries":{"type":"array","items":{"type":"object","properties":{"participantId":{"type":["string","null"],"format":"uuid","description":"ID of the conversation participant who produced this entry. References participants[].id."},"role":{"type":["string","null"],"enum":["AGENT","CUSTOMER"],"description":"Convenience role derived from participant type"},"text":{"type":"string","description":"Transcript text for this entry"},"startOffsetMs":{"type":"integer","minimum":0,"description":"Start time offset in milliseconds from the start of the conversation"},"endOffsetMs":{"type":"integer","minimum":0,"description":"End time offset in milliseconds from the start of the conversation"}},"required":["participantId","role","text","startOffsetMs","endOffsetMs"],"description":"A single transcript entry"},"description":"Ordered list of transcript entries from the chat"}},"required":["participants","entries"],"description":"Chat transcript response"}},"required":["data"]}}},"description":"Transcript for the specified chat"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1ChatByIdTranscript","tags":["Chat"],"summary":"Get chat transcript","description":"Fetch the full transcript (messages) for a specific chat.","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","description":"ID of the chat to fetch transcript for"},"required":true}]}},"/v1/chat/{id}/metrics":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"metricDefinitionId":{"type":"string","format":"uuid","description":"Unique identifier for the metric definition"},"slug":{"type":"string","description":"Stable metric slug"},"metricId":{"type":"string","description":"Alias of `slug` retained for backwards compatibility. Same value as `slug`."},"name":{"type":"string","description":"Name of the metric"},"description":{"type":"string","description":"Description of what the metric measures"},"type":{"type":"string","enum":["COUNT","NUMERIC","BOOLEAN","SCALE","TEXT","CLASSIFICATION","OFFSET"],"description":"Type of value this metric produces"},"scope":{"type":"string","enum":["GLOBAL","PER_PARTICIPANT"],"description":"Whether metric is global or per-participant"},"unit":{"type":"object","properties":{"name":{"type":"string","description":"Name of the unit"},"symbol":{"type":["string","null"],"description":"Symbol for the unit"}},"required":["name","symbol"],"description":"Unit information if applicable"},"values":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"}],"description":"The metric value (type depends on outputType). Present only on SUCCESS rows; omitted for NOT_APPLICABLE / DATA_MISSING / ERROR."},"callId":{"type":"string","format":"uuid","description":"ID of the call this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"chatId":{"type":"string","format":"uuid","description":"ID of the chat this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"captureStatus":{"type":"string","enum":["SUCCESS","NOT_APPLICABLE","DATA_MISSING","ERROR"],"description":"Result state of this metric computation. SUCCESS carries a real `value`; NOT_APPLICABLE / DATA_MISSING / ERROR do not (the `value` field is omitted). Non-SUCCESS rows only appear when the request includes ?status=all."},"errorMessage":{"type":"string","description":"Error detail when captureStatus is ERROR — e.g. provider down, LLM timeout. Undefined for other statuses."},"context":{"type":"string","enum":["CALL","SEGMENT","SEGMENT_RANGE"],"description":"Context level: CALL (entire conversation), SEGMENT (single segment), SEGMENT_RANGE (between/across segments)"},"participantRole":{"type":"string","enum":["agent","customer"],"description":"Role of participant (only for PER_PARTICIPANT metrics)"},"valueReasoning":{"type":"string","description":"Explanation for the metric value (especially useful for AI-computed metrics)"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence score (0-1) for the computed value. Defaults to 1.0 for deterministic metrics. Omitted on non-SUCCESS rows."},"computedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the metric was computed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that triggered this metric computation"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Segment information (for SEGMENT context metrics)"},"fromSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Starting segment information (for SEGMENT_RANGE context metrics)"},"toSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Ending segment information (for SEGMENT_RANGE context metrics)"}},"required":["captureStatus","context","computedAt"],"title":"Standard metric value","description":"A metric value entry. Applies to every metric."},{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"}],"description":"The metric value (type depends on outputType). Present only on SUCCESS rows; omitted for NOT_APPLICABLE / DATA_MISSING / ERROR."},"callId":{"type":"string","format":"uuid","description":"ID of the call this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"chatId":{"type":"string","format":"uuid","description":"ID of the chat this value was computed on. Only set when the response spans multiple conversations (e.g. job-scoped metric values)."},"captureStatus":{"type":"string","enum":["SUCCESS","NOT_APPLICABLE","DATA_MISSING","ERROR"],"description":"Result state of this metric computation. SUCCESS carries a real `value`; NOT_APPLICABLE / DATA_MISSING / ERROR do not (the `value` field is omitted). Non-SUCCESS rows only appear when the request includes ?status=all."},"errorMessage":{"type":"string","description":"Error detail when captureStatus is ERROR — e.g. provider down, LLM timeout. Undefined for other statuses."},"context":{"type":"string","enum":["CALL","SEGMENT","SEGMENT_RANGE"],"description":"Context level: CALL (entire conversation), SEGMENT (single segment), SEGMENT_RANGE (between/across segments)"},"participantRole":{"type":"string","enum":["agent","customer"],"description":"Role of participant (only for PER_PARTICIPANT metrics)"},"valueReasoning":{"type":"string","description":"Explanation for the metric value (especially useful for AI-computed metrics)"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence score (0-1) for the computed value. Defaults to 1.0 for deterministic metrics. Omitted on non-SUCCESS rows."},"computedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the metric was computed"},"policyIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of metric policies that triggered this metric computation"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Segment information (for SEGMENT context metrics)"},"fromSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Starting segment information (for SEGMENT_RANGE context metrics)"},"toSegment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"Ending segment information (for SEGMENT_RANGE context metrics)"},"propertyVerdicts":{"type":"array","items":{"type":"object","properties":{"propertyName":{"type":"string","description":"The call property checked, as sent at ingest"},"expectedValue":{"type":"string","description":"The value supplied at ingest, frozen at scoring time"},"observedValue":{"type":"string","description":"What the transcript said instead. Only present when verdict is MISMATCH."},"verdict":{"type":"string","enum":["MATCH","MISMATCH","TRANSCRIPTION_ERROR","NOT_MENTIONED"],"description":"How this property resolved against the transcript. NOT_MENTIONED means the subject never came up and is not a mismatch."},"reasoning":{"type":"string","description":"Judge reasoning for this verdict"},"segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Segment ID"},"text":{"type":"string","description":"Segment text content"},"startOffsetMs":{"type":"number","description":"Start time offset in milliseconds"},"endOffsetMs":{"type":"number","description":"End time offset in milliseconds"}},"required":["id","text","startOffsetMs","endOffsetMs"],"description":"The transcript segment this property was referred to in: the conflicting value for MISMATCH, the confirming reference for MATCH. Omitted for NOT_MENTIONED and when the verdict could not be anchored."}},"required":["propertyName","expectedValue","verdict"]},"description":"Per-property verdicts for the Property Mismatch metric, in the order the properties were checked. Omitted for every other metric."}},"required":["captureStatus","context","computedAt"],"title":"Property verification metric value","description":"Returned for the Property Mismatch metric (`property_transcript_mismatch`): the standard entry plus the per-property verdict breakdown."}]},"description":"Array of metric values (multiple for PER_PARTICIPANT metrics, or multiple segments/turns)"}},"required":["metricDefinitionId","slug","metricId","name","description","type","scope","values"],"description":"Metric data grouped by metric definition"},"description":"Conversation metrics response payload grouped by metric definition"}},"required":["data"]}}},"description":"Metrics for a specific chat"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1ChatByIdMetrics","tags":["Chat"],"summary":"List chat metrics","description":"Fetch all metrics for a specific chat, including both system-generated and custom metrics. Only returns rows from the **latest** metric-collection job per metric — if the same metric has been recomputed, prior runs are excluded and remain in the metric history. By default returns only successfully computed metrics; pass `?status=all` to also include rows that resolved as NOT_APPLICABLE / DATA_MISSING / ERROR (the `value` field is omitted on those entries — check `captureStatus`).","parameters":[{"in":"query","name":"flatten","schema":{"type":"string","description":"Whether to return a flat list instead of grouped by metric definition (default: false)"}},{"in":"query","name":"status","schema":{"type":"string","enum":["success","all"],"default":"success","description":"Filter metrics by capture status. `success` (default) returns only successfully computed metrics — backwards-compatible with the historical behavior. `all` also returns NOT_APPLICABLE / DATA_MISSING / ERROR rows (with `value` omitted), so clients can distinguish \"still computing\" from \"computed but no value\" and exit retry loops correctly."}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}]}},"/v1/metric/definitions":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMetricDefinitionsResponse"}}},"description":"Cursor-paginated metric definitions available in the project"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricDefinitions","tags":["Metric"],"summary":"List metric definitions","description":"Fetch metric definitions available in the project, including both system-generated and custom metrics. Results are ordered by immutable definition ID; pass `nextCursor` to retrieve the following page.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":500,"default":500}},{"in":"query","name":"after","schema":{"type":"string"}}]},"post":{"responses":{"201":{"description":"The created metric definition","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CreateMetricDefinitionResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1MetricDefinitions","tags":["Metric"],"summary":"Create custom metric definition","description":"Create a new metric definition. The `calculationType` field selects the variant: LLM_JUDGE (LLM-evaluated), FORMULA (computed from a math expression over other metrics), or PATTERN (detects a trigger→outcome pattern within a window). To create a threshold on top of an existing metric, use `POST /metric/definitions/{idOrSlug}/thresholds` instead.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMetricDefinitionInput"}}}}}},"/v1/metric/definitions/{idOrSlug}":{"get":{"responses":{"200":{"description":"The metric definition","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricDefinitionResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricDefinitionsByIdOrSlug","tags":["Metric"],"summary":"Get a metric definition","description":"Fetch a single metric definition by its UUID or its stable `slug` (e.g. `customer_satisfaction`). Resolution is scoped to the project — a project-owned metric wins over an org-wide one, which wins over a system metric of the same `slug`.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"The metric definition's Roark ID (UUID) or its stable `slug` (e.g. `customer_satisfaction`).","schema":{"type":"string"}}]},"put":{"responses":{"200":{"description":"The updated metric definition (with `versionId` advanced to the new version)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UpdateMetricDefinitionResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1MetricDefinitionsByIdOrSlug","tags":["Metric"],"summary":"Update a metric definition","description":"Update the editable subset of a custom metric definition, addressed by its UUID or its stable `slug`. Only the supplied fields are changed; omitted fields are left unchanged. Every update creates a new immutable version; the response carries the advanced `versionId`. Immutable fields (scope, outputType, calcType, …) are rejected, and which fields are editable depends on the metric (e.g. derived metrics only allow `name`).  Roark's own metrics are rejected here: this endpoint edits the shared definition, which every workspace sees. To change one for your workspace alone, edit its variant with PUT /v1/metric/definitions/{idOrSlug}/variants/{variantId}, which forks it for you and leaves every other workspace on the original.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"The metric definition's Roark ID (UUID) or its stable `slug` (e.g. `customer_satisfaction`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMetricDefinitionInput"}}}}},"delete":{"responses":{"200":{"description":"The metric definition was archived","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Roark ID of the archived metric definition"},"deleted":{"type":"boolean","const":true,"description":"Always true when the metric definition was successfully archived"}},"required":["id","deleted"],"title":"DeleteMetricDefinitionResponse","description":"Result of archiving (soft-deleting) a metric definition"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Conflict error"},"example":{"type":"conflict","code":"resource_in_use","message":"The resource is in use and cannot be deleted"}}},"description":"Conflict"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1MetricDefinitionsByIdOrSlug","tags":["Metric"],"summary":"Delete a metric definition","description":"Archives (soft-deletes) a custom metric definition, addressed by its UUID or its stable `slug`. The metric is hidden from all reads and stops being collected, but its record and previously collected values are retained. System metrics cannot be deleted. Fails with 409 if the metric is still used as a source by a derived metric (delete those first).","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"The metric definition's Roark ID (UUID) or its stable `slug` (e.g. `customer_satisfaction`).","schema":{"type":"string"}}]}},"/v1/metric/definitions/{idOrSlug}/thresholds":{"post":{"responses":{"201":{"description":"The created threshold (as a metric definition)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ThresholdMetricResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1MetricDefinitionsByIdOrSlugThresholds","tags":["Metric"],"summary":"Create a threshold on a metric","description":"Create a boolean threshold derived from an existing metric. The source metric is addressed by its UUID or its stable `slug`. The threshold fires when the source metric meets the comparison condition. Scope and supported contexts are inherited from the source metric.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"The metric definition's Roark ID (UUID) or its stable `slug` (e.g. `customer_satisfaction`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThresholdInput"}}}}}},"/v1/metric/definitions/{idOrSlug}/variants":{"get":{"responses":{"200":{"description":"The variants visible to your organization","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricVariantListResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricDefinitionsByIdOrSlugVariants","tags":["Metric"],"summary":"List a metric’s variants","description":"Every configuration of this metric your organization can use: Roark’s own variants and any your\norganization has added or forked. `isDefault` marks the one the metric is scored with when nothing\npins another; pass any variant’s `id` as `sourceVariantId` to pin it on a derived metric.\n\nAuto-managed variants (the ones a package materializes for you) are not listed: they are engine state,\nnot configuration you author.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"Metric definition UUID or its stable slug.","schema":{"type":"string"}}]},"post":{"responses":{"201":{"description":"The created variant","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricVariantResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1MetricDefinitionsByIdOrSlugVariants","tags":["Metric"],"summary":"Create a metric variant","description":"Add a configuration of this metric for your organization, seeded from its Default. Edit it with\nPUT to change what it measures, then pin it where you want it used.\n\nThreshold metrics have no variants: their configuration comes from the metric they derive from.\nMetrics in a package that manages its own variants reject this too.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"Metric definition UUID or its stable slug.","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMetricVariantInput"}}}}}},"/v1/metric/definitions/{idOrSlug}/variants/{variantId}":{"get":{"responses":{"200":{"description":"The variant","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricVariantResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricDefinitionsByIdOrSlugVariantsByVariantId","tags":["Metric"],"summary":"Get a metric variant","description":"One configuration of this metric, by id.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"Metric definition UUID or its stable slug.","schema":{"type":"string"}},{"name":"variantId","in":"path","required":true,"description":"Variant UUID.","schema":{"type":"string","format":"uuid"}}]},"put":{"responses":{"200":{"description":"The updated variant, or your organization’s fork of it","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricVariantResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1MetricDefinitionsByIdOrSlugVariantsByVariantId","tags":["Metric"],"summary":"Update a metric variant","description":"Rename a variant, change its configuration, or both. Every configuration change creates a new\nimmutable version and advances `versionId`; the response carries the advanced value.\n\n**Editing one of Roark’s own variants forks it for your organization.** The response carries the\nnew variant’s `id`, which will differ from the one in the path, and `isSystem` becomes false. Roark’s\nvariant is untouched and other organizations keep it. DELETE your fork to go back to it.\n\nWhich fields are editable depends on the metric: some Roark metrics lock their prompt or output\nconfiguration, and a locked field is rejected rather than ignored.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"Metric definition UUID or its stable slug.","schema":{"type":"string"}},{"name":"variantId","in":"path","required":true,"description":"Variant UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMetricVariantInput"}}}}},"delete":{"responses":{"200":{"description":"The variant was deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DeleteMetricVariantResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1MetricDefinitionsByIdOrSlugVariantsByVariantId","tags":["Metric"],"summary":"Delete a metric variant","description":"Remove one of your organization’s variants. Anything pinned to it falls back to the Default, so\ndeleting a fork of a Roark variant returns you to Roark’s configuration.\n\nRoark’s own variants cannot be deleted, and neither can a Default. Values already collected under\nthe deleted variant are retained.","parameters":[{"name":"idOrSlug","in":"path","required":true,"description":"Metric definition UUID or its stable slug.","schema":{"type":"string"}},{"name":"variantId","in":"path","required":true,"description":"Variant UUID.","schema":{"type":"string","format":"uuid"}}]}},"/v1/metric/policies":{"get":{"responses":{"200":{"description":"Paginated list of metric policies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMetricPoliciesResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricPolicies","tags":["Metric Policy"],"summary":"List metric policies","description":"Returns a paginated list of metric policies for the project, including system policies.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of policies to return (default: 20, max: 50)","example":20}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - use the nextCursor value from a previous response"}},{"in":"query","name":"status","schema":{"type":"string","enum":["ACTIVE","INACTIVE"],"description":"Filter by policy status"}}]},"post":{"responses":{"201":{"description":"The created metric policy","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricPolicyResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1MetricPolicies","tags":["Metric Policy"],"summary":"Create a metric policy","description":"Creates a new metric policy. Policies define which metrics to collect and under what conditions.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMetricPolicyInput"}}}}}},"/v1/metric/policies/{policyId}":{"get":{"responses":{"200":{"description":"The requested metric policy","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricPolicyResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricPoliciesByPolicyId","tags":["Metric Policy"],"summary":"Get metric policy by ID","description":"Returns a specific metric policy with its conditions and metrics.","parameters":[{"name":"policyId","in":"path","required":true,"description":"The ID of the metric policy to retrieve","schema":{"type":"string","format":"uuid"}}]},"put":{"responses":{"200":{"description":"The updated metric policy","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricPolicyResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1MetricPoliciesByPolicyId","tags":["Metric Policy"],"summary":"Update a metric policy","description":"Updates an existing metric policy. System policies cannot be modified.","parameters":[{"name":"policyId","in":"path","required":true,"description":"The ID of the metric policy to update","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMetricPolicyInput"}}}}},"delete":{"responses":{"200":{"description":"Metric policy deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean","description":"Whether the policy was deleted"}},"required":["deleted"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1MetricPoliciesByPolicyId","tags":["Metric Policy"],"summary":"Delete a metric policy","description":"Soft-deletes a metric policy. System policies cannot be deleted.","parameters":[{"name":"policyId","in":"path","required":true,"description":"The ID of the metric policy to delete","schema":{"type":"string","format":"uuid"}}]}},"/v1/metric/collection-jobs":{"get":{"responses":{"200":{"description":"Paginated list of metric collection jobs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMetricCollectionJobsResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricCollection-jobs","tags":["Metric Collection Job"],"summary":"List metric collection jobs","description":"Returns a paginated list of metric collection jobs for the project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of jobs to return (default: 20, max: 50)","example":20}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - use the nextCursor value from a previous response"}},{"in":"query","name":"status","schema":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","CANCELED"],"description":"Filter by job status"}}]},"post":{"responses":{"201":{"description":"The created metric collection job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricCollectionJobResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1MetricCollection-jobs","tags":["Metric Collection Job"],"summary":"Create and run a metric collection job","description":"Creates a metric collection job for the specified calls or chats and metrics, then triggers processing. Provide exactly one of callIds or chatIds.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMetricCollectionJobInput"}}}}}},"/v1/metric/collection-jobs/{jobId}":{"get":{"responses":{"200":{"description":"The requested metric collection job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricCollectionJobResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricCollection-jobsByJobId","tags":["Metric Collection Job"],"summary":"Get metric collection job by ID","description":"Returns a specific metric collection job with progress information.","parameters":[{"name":"jobId","in":"path","required":true,"description":"The ID of the metric collection job to retrieve","schema":{"type":"string","format":"uuid"}}]}},"/v1/metric/collection-jobs/{jobId}/retry":{"post":{"responses":{"201":{"description":"The newly created (retry) metric collection job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricCollectionJobResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1MetricCollection-jobsByJobIdRetry","tags":["Metric Collection Job"],"summary":"Retry a metric collection job","description":"Creates a new metric collection job using the same conversations and metrics as a previous job, then triggers processing. The previous job must be in a terminal state (COMPLETED, FAILED, or CANCELED). Returns the newly created job — track its id for downstream fetches.","parameters":[{"name":"jobId","in":"path","required":true,"description":"The ID of the previous metric collection job to retry","schema":{"type":"string","format":"uuid"}}]}},"/v1/metric/collection-jobs/{jobId}/metric-values":{"get":{"responses":{"200":{"description":"Metric values produced by the job, grouped by metric definition","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricCollectionJobMetricValuesResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1MetricCollection-jobsByJobIdMetric-values","tags":["Metric Collection Job"],"summary":"Get metric values produced by a metric collection job","description":"Returns the metric values produced by the specified job, grouped by metric definition. Unlike `GET /v1/call/:callId/metrics` (which returns the latest values on a call, regardless of which job computed them), this endpoint returns exactly the values *this* job produced — including for calls whose live values have since been overwritten by a later job. By default returns only SUCCESS rows; pass `?status=all` to also include NOT_APPLICABLE / DATA_MISSING / ERROR.","parameters":[{"in":"query","name":"status","schema":{"type":"string","enum":["success","all"],"default":"success","description":"Filter metrics by capture status. `success` (default) returns only successfully computed metrics; `all` also returns NOT_APPLICABLE / DATA_MISSING / ERROR rows with the `value` field omitted."}},{"schema":{"type":"string"},"in":"path","name":"jobId","required":true}]}},"/v1/persona":{"get":{"responses":{"200":{"description":"List of personas","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"]}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Persona","tags":["Simulation Persona"],"summary":"List personas","description":"Returns a paginated list of personas for the authenticated project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"in":"query","name":"after","schema":{"type":"string"}},{"in":"query","name":"searchText","schema":{"type":"string"}}]},"post":{"responses":{"201":{"description":"The created persona","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"]}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Persona","tags":["Simulation Persona"],"summary":"Create a new persona","description":"Creates a new persona for the authenticated project.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Defaults to the languages the persona speaks."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. Defaults to language-appropriate phrases when omitted or sent as null."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}}},"required":["name","language","accent","gender"],"title":"CreatePersonaInput","description":"Input for creating a new persona"}}}}}},"/v1/persona/{personaId}":{"get":{"responses":{"200":{"description":"The requested persona","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1PersonaByPersonaId","tags":["Simulation Persona"],"summary":"Get persona by ID","description":"Returns a specific persona by its ID.","parameters":[{"name":"personaId","in":"path","required":true,"description":"The ID of the persona to retrieve","schema":{"type":"string"}}]},"put":{"responses":{"200":{"description":"The updated persona","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the persona"},"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"}},"required":["id","name","language","understoodLanguages","accent","age","gender","backgroundNoise","speechPace","speechClarity","hasDisfluencies","baseEmotion","intentClarity","confirmationStyle","memoryReliability","responseTiming","idleMessages","idleTimeoutSeconds","idleMessageMaxSpokenCount","idleMessageResetCountOnUserSpeechEnabled","properties","createdAt","updatedAt"]}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1PersonaByPersonaId","tags":["Simulation Persona"],"summary":"Update a persona","description":"Updates an existing persona by its ID.","parameters":[{"name":"personaId","in":"path","required":true,"description":"The ID of the persona to update","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name the agent will identify as during conversations"},"displayName":{"type":["string","null"],"description":"Label shown in place of the name across the dashboard (e.g. a short descriptor like \"Irate Escalator\"). The persona still identifies as `name` on calls. Omit or set null to display the name itself."},"description":{"type":["string","null"],"description":"Human-readable description of the persona"},"language":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"],"description":"Primary language ISO 639-1 code for the persona"},"secondaryLanguage":{"type":["string","null"],"enum":["EN"],"description":"Secondary language ISO 639-1 code for code-switching (e.g., Hinglish, Spanglish)"},"understoodLanguages":{"type":"array","items":{"type":"string","enum":["EN","ES","DE","HI","FR","NL","AR","EL","IT","ID","TH","JA","TL","MS","ZH","TR","PT","HE"]},"minItems":1,"description":"Languages the persona can understand. Multilingual combinations are limited by multilingual speech recognition support."},"accent":{"type":"string","enum":["US","US_X_SOUTH","GB","ES","DE","IN","FR","NL","SA","GR","AU","IT","ID","TH","JP","NZ","PH","SG","MY","HK","TR","PT","IL"],"description":"Accent of the persona, defined using ISO 3166-1 alpha-2 country codes with optional variants"},"age":{"type":"string","enum":["CHILD","TEENAGER","ADULT","ELDERLY"],"default":"ADULT","description":"How old the caller sounds and behaves. Only ages the persona's accent has a voice for are accepted; defaults to ADULT, which every accent supports."},"gender":{"type":"string","enum":["MALE","FEMALE"],"description":"Gender of the persona"},"backgroundNoise":{"type":"string","enum":["NONE","AIRPORT","CHILDREN_PLAYING","CITY","COFFEE_SHOP","DRIVING","OFFICE","THUNDERSTORM"],"default":"NONE","description":"Background noise setting"},"speechPace":{"type":"string","enum":["SUPER_SLOW","SLOW","NORMAL","FAST","SUPER_FAST"],"default":"NORMAL","description":"Speech pace of the persona"},"speechClarity":{"type":"string","enum":["CLEAR","VAGUE","RAMBLING"],"default":"CLEAR","description":"Speech clarity of the persona"},"hasDisfluencies":{"type":"boolean","default":false,"description":"Whether the persona uses filler words like \"um\" and \"uh\""},"baseEmotion":{"type":"string","enum":["NEUTRAL","CHEERFUL","CONFUSED","FRUSTRATED","SKEPTICAL","RUSHED","DISTRACTED"],"default":"NEUTRAL","description":"Base emotional state of the persona"},"intentClarity":{"type":"string","enum":["CLEAR","INDIRECT","VAGUE"],"default":"CLEAR","description":"How clearly the persona expresses their intentions"},"confirmationStyle":{"type":"string","enum":["EXPLICIT","VAGUE"],"default":"EXPLICIT","description":"How the persona confirms information"},"memoryReliability":{"type":"string","enum":["HIGH","LOW"],"default":"HIGH","description":"How reliable the persona's memory is"},"responseTiming":{"type":"string","enum":["RELAXED","NORMAL","QUICK"],"default":"NORMAL","description":"Controls how quickly the persona responds to pauses in conversation (QUICK, NORMAL, RELAXED)"},"backstoryPrompt":{"type":["string","null"],"description":"Background story and behavioral patterns for the persona","example":"A busy professional calling during lunch break"},"idleMessages":{"type":["array","null"],"items":{"type":"string"},"description":"Messages the persona will say when the agent goes silent during a call. null = \"Automatic\": language-appropriate defaults are used at call time."},"idleTimeoutSeconds":{"type":"integer","minimum":5,"maximum":60,"default":10,"description":"Seconds of silence before the persona sends an idle message"},"idleMessageMaxSpokenCount":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Maximum number of idle messages the persona will send before giving up"},"idleMessageResetCountOnUserSpeechEnabled":{"type":"boolean","default":true,"description":"Whether the idle message counter resets when the agent speaks"},"properties":{"type":"object","additionalProperties":{},"default":{},"description":"Additional custom properties about the persona","example":{"age":35,"zipCode":"94105","occupation":"Software Engineer"}}},"title":"UpdatePersonaInput","description":"Input for updating an existing persona"}}}}},"delete":{"responses":{"200":{"description":"The persona was deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the deleted persona"},"deleted":{"type":"boolean","const":true,"description":"Always true when the persona was successfully deleted"}},"required":["id","deleted"]}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1PersonaByPersonaId","tags":["Simulation Persona"],"summary":"Delete a persona","description":"Soft-deletes a persona by its ID. The persona is hidden from all reads and stops being available to new simulations, but its record and history are retained. System personas cannot be deleted.","parameters":[{"name":"personaId","in":"path","required":true,"description":"The ID of the persona to delete","schema":{"type":"string"}}]}},"/v1/simulation/run":{"post":{"responses":{"200":{"description":"The run that was started","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RunSimulationResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1SimulationRun","tags":["Simulation"],"summary":"Run a simulation","description":"Starts a simulation and returns the run.\n\nSend `template` to run one of the built-in templates: it supplies the metrics and checks,\nand for some templates the flows too, so the request only names the agent and the direction.\nSend `plan` to describe a simulation yourself and run it once. Send `planId` to run a plan\nyou already have.\n\n`template` and `plan` both resolve to a run plan, returned as `simulationRunPlanId`. Add\n`saveAsPlan` to keep it, or read it back to see exactly what ran. A plan built from a\ntemplate is a snapshot: retuning the template later never changes what that plan runs, which\nis what makes a saved one safe to pin in CI.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunSimulationInput"}}}}}},"/v1/simulation/environment":{"get":{"responses":{"200":{"description":"List of environments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEnvironmentsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationEnvironment","tags":["Simulation Environment"],"summary":"List environments","description":"Returns a paginated list of environments: the project's own plus the environments Roark curates and shares across every project. Reference one by id when setting a customer flow variant's environment.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"in":"query","name":"after","schema":{"type":"string"}}]},"post":{"responses":{"201":{"description":"The created environment","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvironmentResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1SimulationEnvironment","tags":["Simulation Environment"],"summary":"Create an environment","description":"Creates an environment for the project: a noise bed and the level it plays at. Reference it by id when setting a customer flow variant's environment. Roark's curated presets always play at the default level, so this is how a project gets the same bed louder or quieter.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEnvironmentInput"}}}}}},"/v1/simulation/environment/{environmentId}":{"get":{"responses":{"200":{"description":"The requested environment","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvironmentResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationEnvironmentByEnvironmentId","tags":["Simulation Environment"],"summary":"Get environment by ID","description":"Returns a single environment by its ID.","parameters":[{"in":"path","name":"environmentId","schema":{"type":"string","format":"uuid"},"required":true}]},"put":{"responses":{"200":{"description":"The updated environment","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvironmentResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1SimulationEnvironmentByEnvironmentId","tags":["Simulation Environment"],"summary":"Update an environment","description":"Updates one of the project's environments. Only the fields sent are changed. Runs already built keep the snapshot they were built with. Roark-curated environments cannot be edited (403).","parameters":[{"in":"path","name":"environmentId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEnvironmentInput"}}}}},"delete":{"responses":{"200":{"description":"The environment was deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DeleteEnvironmentResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Conflict error"},"example":{"type":"conflict","code":"resource_in_use","message":"The resource is in use and cannot be deleted"}}},"description":"Conflict"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1SimulationEnvironmentByEnvironmentId","tags":["Simulation Environment"],"summary":"Delete an environment","description":"Soft-deletes one of the project's environments. It disappears from reads and cannot be picked for new runs; runs already built keep their snapshot. Refused (409) while a live customer flow variant still uses it: move those variants first. Roark-curated environments cannot be deleted (403).","parameters":[{"in":"path","name":"environmentId","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/simulation/plan":{"get":{"responses":{"200":{"description":"Paginated list of run plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetRunPlansResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationPlan","tags":["Simulation Run Plan"],"summary":"List run plans","description":"Returns a paginated list of simulation run plans. Optionally filter by search text or agent ID.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of run plans to return (default: 20, max: 50)","example":20}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - use the nextCursor value from a previous response"}},{"in":"query","name":"searchText","schema":{"type":"string","description":"Search text to filter run plans by name"}},{"in":"query","name":"agentId","schema":{"type":"string","format":"uuid","description":"Filter run plans by agent ID"}}]},"post":{"responses":{"201":{"description":"The created run plan","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CreateRunPlanResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1SimulationPlan","tags":["Simulation Run Plan"],"summary":"Create a run plan","description":"Creates a new simulation run plan.\n\nTo run a simulation, use POST /v1/simulation/run instead: it starts a run from a plan or\nfrom an inline configuration, and takes runtime variables. Create a plan here when you want\na reusable, named one to run later.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunPlanInput"}}}}}},"/v1/simulation/plan/{planId}":{"put":{"responses":{"200":{"description":"The updated run plan","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RunPlanResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Conflict error"},"example":{"type":"conflict","code":"resource_in_use","message":"The resource is in use and cannot be deleted"}}},"description":"Conflict"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1SimulationPlanByPlanId","tags":["Simulation Run Plan"],"summary":"Update a run plan","description":"Updates an existing simulation run plan by its ID.","parameters":[{"name":"planId","in":"path","required":true,"description":"The ID of the run plan to update","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRunPlanInput"}}}}},"delete":{"responses":{"200":{"description":"Run plan deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean","description":"Whether the run plan was deleted"}},"required":["deleted"]}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Conflict error"},"example":{"type":"conflict","code":"resource_in_use","message":"The resource is in use and cannot be deleted"}}},"description":"Conflict"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1SimulationPlanByPlanId","tags":["Simulation Run Plan"],"summary":"Delete a run plan","description":"Soft-deletes a simulation run plan by its ID.","parameters":[{"name":"planId","in":"path","required":true,"description":"The ID of the run plan to delete","schema":{"type":"string","format":"uuid"}}]},"get":{"responses":{"200":{"description":"The requested run plan","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RunPlanResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationPlanByPlanId","tags":["Simulation Run Plan"],"summary":"Get run plan by ID","description":"Returns a specific simulation run plan by its ID.","parameters":[{"name":"planId","in":"path","required":true,"description":"The ID of the run plan to retrieve","schema":{"type":"string","format":"uuid"}}]}},"/v1/simulation/plan/jobs":{"get":{"responses":{"200":{"description":"Paginated list of simulation plan jobs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSimulationPlanJobsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationPlanJobs","tags":["Simulation Run Plan Job"],"summary":"List simulation plan jobs","description":"Returns a paginated list of simulation run plan jobs. Filter by status, plan ID, or label to find specific simulation batches.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of plan jobs to return (default: 20, max: 50)","example":20}},{"in":"query","name":"after","schema":{"type":"string","format":"uuid","description":"Cursor for pagination - use the nextCursor value from a previous response","example":"550e8400-e29b-41d4-a716-446655440000"}},{"in":"query","name":"status","schema":{"type":"string","enum":["PENDING","QUEUED","CREATING_SNAPSHOTS","CREATING_SIMULATIONS","PREPARING_CAPACITY","RUNNING_SIMULATIONS","COMPLETED","FAILED","TIMED_OUT","CANCELLED","CANCELLING","ENDING_SIMULATIONS"],"description":"Filter by plan job status (PENDING, QUEUED, CREATING_SNAPSHOTS, CREATING_SIMULATIONS, PREPARING_CAPACITY, RUNNING_SIMULATIONS, COMPLETED, FAILED, TIMED_OUT, CANCELLED, CANCELLING, ENDING_SIMULATIONS)","example":"COMPLETED"}},{"in":"query","name":"simulationRunPlanId","schema":{"type":"string","format":"uuid","description":"Filter by simulation run plan ID","example":"550e8400-e29b-41d4-a716-446655440000"}},{"in":"query","name":"labelId","schema":{"type":"string","format":"uuid","description":"Filter by label ID attached to the plan job. Use this if you know the label ID.","example":"550e8400-e29b-41d4-a716-446655440000"}},{"in":"query","name":"labelName","schema":{"type":"string","description":"Filter by label name attached to the plan job. More user-friendly alternative to labelId. Case-insensitive.","example":"production-ready"}}]}},"/v1/simulation/plan/job/{jobId}":{"get":{"responses":{"200":{"description":"Successfully retrieved simulation plan job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GetSimulationPlanJobResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Simulation plan job not found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationPlanJobByJobId","tags":["Simulation Run Plan Job"],"summary":"Get simulation plan job","description":"Retrieve details of a simulation plan job including all associated simulation jobs (calls)","parameters":[{"in":"path","name":"jobId","schema":{"type":"string","format":"uuid"},"required":true,"example":"7f3e4d2c-8a91-4b5c-9e6f-1a2b3c4d5e6f","description":"Simulation run plan job ID"}]}},"/v1/simulation/plan/{planId}/job":{"post":{"responses":{"200":{"description":"Successfully triggered simulation run plan","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RunSimulationPlanResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Insufficient credit"},"example":{"type":"payment_required","code":"insufficient_credits","message":"Not enough credit to start this work. Add credit and try again."}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Simulation run plan not found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1SimulationPlanByPlanIdJob","tags":["Simulation Run Plan Job"],"deprecated":true,"summary":"Run a simulation plan","description":"Deprecated: use POST /v1/simulation/run, which does the same thing and can also take the\nplan configuration inline, so a one-off run does not have to create a plan first.\n\nCreates and executes a job for an existing simulation run plan. Optionally provide runtime\nvariables to override plan-defined variables.","parameters":[{"in":"path","name":"planId","schema":{"type":"string","format":"uuid"},"required":true,"example":"7f3e4d2c-8a91-4b5c-9e6f-1a2b3c4d5e6f","description":"Simulation run plan ID"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunSimulationPlanBody"}}}}}},"/v1/simulation/template":{"get":{"responses":{"200":{"description":"The built-in simulation templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSimulationTemplatesResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationTemplate","tags":["Simulation Template"],"summary":"List simulation templates","description":"Returns the built-in simulation templates, each resolved against this project: the metric and\ncheck definitions it collects, and the flows it runs with the variants it covers.\n\nA template is a preset rather than a stored object, so building a run from one produces an\nordinary run plan you own and can edit afterwards. Pass a `slug` as `template` to\nPOST /v1/simulation/run.\n\nEvery entry is complete, so there is no per-template endpoint to follow up with, and the list\nis a fixed catalogue rather than a paginated one. Only templates a request can actually run\nare listed."}},"/v1/simulation/job/lookup":{"get":{"responses":{"200":{"description":"Successfully found simulation job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SimulationJobResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"No active lease or associated job found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationJobLookup","tags":["Simulation Job"],"summary":"Lookup by phone number","description":"Find the matching simulation using the number used by the Roark simulation agent.","parameters":[{"in":"query","name":"roarkPhoneNumber","schema":{"type":"string"},"required":true,"example":"+15551234567","description":"Phone number provisioned by Roark for the simulation job in E.164 format. In the case of an inbound simulation, this is the number that calls your agent; in the case of an outbound simulation, this is the number you call from your agent."},{"in":"query","name":"callReceivedAt","schema":{"type":"string","format":"date-time"},"required":false,"example":"2024-01-15T10:30:00Z","description":"ISO 8601 timestamp of when the call was received. Alternatively, any time between the start and end of the call is valid. Defaults to the current time, which fetches any jobs that are currently ongoing."}]}},"/v1/simulation/job/{jobId}":{"get":{"responses":{"200":{"description":"Successfully found simulation job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SimulationJobResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Simulation job not found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1SimulationJobByJobId","tags":["Simulation Job"],"summary":"Get simulation by ID","description":"Get a individual simulation run directly by its ID. This is generally part of a larger simulation run plan job.","parameters":[{"in":"path","name":"jobId","schema":{"type":"string","format":"uuid"},"required":true,"example":"7f3e4d2c-8a91-4b5c-9e6f-1a2b3c4d5e6f","description":"Simulation job ID"}]}},"/v1/customer-flow":{"get":{"responses":{"200":{"description":"List of customer flows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCustomerFlowsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Customer-flow","tags":["Customer Flow"],"summary":"List customer flows","description":"Returns a paginated list of customer flows with their agents, expectations, happy path and edge cases. The step graph is the one field omitted: reading it walks the project's whole step graph, so it comes back from the single-flow endpoint instead. Customer flows are how a project describes what to test; they replace the older simulation scenarios.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"in":"query","name":"after","schema":{"type":"string"}},{"in":"query","name":"searchText","schema":{"type":"string"}},{"in":"query","name":"type","schema":{"type":"string","enum":["SCRIPTED","IMPROV","VOICEMAIL"]}},{"in":"query","name":"includeSystem","schema":{"type":"string","enum":["true","false"]}}]},"post":{"responses":{"201":{"description":"The created customer flow","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CustomerFlow"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Customer-flow","tags":["Customer Flow"],"summary":"Create a customer flow","description":"Creates a customer flow. A SCRIPTED flow carries a step graph and gets one way of running it per path through the graph; an IMPROV flow carries the briefs you send. Customer flows replace the older simulation scenarios, so build a flow for anything new.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerFlowInput"}}}}}},"/v1/customer-flow/{flowId}":{"get":{"responses":{"200":{"description":"The requested customer flow","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CustomerFlow"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Customer-flowByFlowId","tags":["Customer Flow"],"summary":"Get customer flow by ID","description":"Returns a customer flow with its happy path, edge cases, expectations and linked agents. Scripted flows also carry their step graph.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}]},"put":{"responses":{"200":{"description":"The updated customer flow","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CustomerFlow"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1Customer-flowByFlowId","tags":["Customer Flow"],"summary":"Update a customer flow","description":"Updates a flow's title, description, branching mode, linked agents or flow-level expectations. The step graph is replaced through PUT /graph.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomerFlowInput"}}}}},"delete":{"responses":{"200":{"description":"Customer flow deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean","description":"Whether the flow was deleted"}},"required":["deleted"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1Customer-flowByFlowId","tags":["Customer Flow"],"summary":"Delete a customer flow","description":"Soft-deletes a customer flow along with its edge cases, expectations and (for scripted flows) its step graph. Run plans that linked it drop it from their test cases.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/customer-flow/{flowId}/graph":{"put":{"responses":{"200":{"description":"The flow graph after the write","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ReplaceFlowStepsResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Conflict error"},"example":{"type":"conflict","code":"resource_in_use","message":"The resource is in use and cannot be deleted"}}},"description":"The write drops branches that currently rejoin. Set allowUnmerge to confirm."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1Customer-flowByFlowIdGraph","tags":["Customer Flow"],"summary":"Replace a scripted flow's steps","description":"Replaces a scripted flow's conversation graph with the tree you send. This is a full replace, not a merge:\na step you omit is removed.\n\nInclude `nodeId` on a step to update the existing one, omit it to create a new step. Where two branches\nrejoin, keep the `mergeIntoNodeIds` references a read gave you. Dropping them un-merges those branches\nand is refused unless `allowUnmerge` is set.\n\nA change to the set of paths re-seeds how the flow runs, which the response reports as\n`variantsReshaped` along with the resulting happy path and edge cases.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceFlowStepsInput"}}}}}},"/v1/customer-flow/{flowId}/happy-path":{"put":{"responses":{"200":{"description":"The updated happy path","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FlowVariant"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1Customer-flowByFlowIdHappy-path","tags":["Customer Flow"],"summary":"Update a flow's happy path","description":"Updates the happy path's title, persona, environment, brief or expectations. Omitted fields are left\nalone; `additionalExpectations` replaces the set wholesale rather than appending.\n\nIts persona and environment are what the edge cases inherit, so changing them here changes every edge\ncase that does not name its own.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlowVariantInput"}}}}}},"/v1/customer-flow/{flowId}/duplicate":{"post":{"responses":{"201":{"description":"The duplicated customer flow","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CustomerFlow"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Customer-flowByFlowIdDuplicate","tags":["Customer Flow"],"summary":"Duplicate a customer flow","description":"Deep-copies a flow into a new project-owned flow. The copy carries the source's description, branching mode, linked agents, flow-level expectations and flow-owned metrics. A scripted flow copies its whole step graph; an improv flow copies its variants (personas, briefs, expectations). Duplicating a Roark-managed flow is how you customise it. Voicemail flows are Roark-managed and cannot be duplicated.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"required":false,"content":{"application/json":{"schema":{}}}}}},"/v1/customer-flow/{flowId}/edge-case":{"post":{"responses":{"201":{"description":"The edge case that was added","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FlowVariant"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Customer-flowByFlowIdEdge-case","tags":["Customer Flow Edge Case"],"summary":"Add an edge case","description":"Adds a variant to an IMPROV flow.\n\nA scripted flow's variants are owned by the path engine, one per path through the graph, so they are\ncreated by editing the graph through PUT /v1/customer-flow/{flowId}/graph rather than here.\n\nLeave personaOverrideId or environmentId unset to inherit the happy path's.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddFlowEdgeCaseInput"}}}}}},"/v1/customer-flow/{flowId}/edge-case/{edgeCaseId}":{"put":{"responses":{"200":{"description":"The updated edge case","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FlowVariant"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1Customer-flowByFlowIdEdge-caseByEdgeCaseId","tags":["Customer Flow Edge Case"],"summary":"Update an edge case","description":"Updates an edge case's title, persona, environment, brief, preceded-by link or expectations. Omitted fields are left alone; `additionalExpectations` replaces the set wholesale rather than appending. Promoting it to the happy path is a separate call, since that also demotes the incumbent.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true},{"in":"path","name":"edgeCaseId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlowVariantInput"}}}}},"delete":{"responses":{"200":{"description":"Edge case removed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean","description":"Whether the variant was deleted"}},"required":["deleted"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1Customer-flowByFlowIdEdge-caseByEdgeCaseId","tags":["Customer Flow Edge Case"],"summary":"Remove an edge case","description":"Soft-deletes a variant. On a scripted flow the path engine re-creates a variant for any path still in the graph, so remove the path through PUT /graph instead if that is what you meant.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true},{"in":"path","name":"edgeCaseId","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/customer-flow/{flowId}/edge-case/{edgeCaseId}/promote":{"post":{"responses":{"200":{"description":"The edge case, now the happy path","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FlowVariant"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Customer-flowByFlowIdEdge-caseByEdgeCaseIdPromote","tags":["Customer Flow Edge Case"],"summary":"Promote an edge case to the happy path","description":"Makes this edge case the flow's happy path, and the outgoing happy path an edge case. Its persona and environment are baked into it first, so edge cases that were inheriting keep the configuration they had.","parameters":[{"in":"path","name":"flowId","schema":{"type":"string","format":"uuid"},"required":true},{"in":"path","name":"edgeCaseId","schema":{"type":"string","format":"uuid"},"required":true}]}},"/v1/http-request-definition":{"get":{"responses":{"200":{"description":"List of HTTP request definitions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/HttpRequestDefinitionResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Http-request-definition","tags":["HTTP Request Definition"],"summary":"List HTTP request definitions","description":"Returns a paginated list of HTTP request definitions for the authenticated project.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of definitions to return (default: 20, max: 50)"}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - definition ID to start after"}}]},"post":{"responses":{"201":{"description":"The created HTTP request definition with signing secret","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HttpRequestDefinitionCreateResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Http-request-definition","tags":["HTTP Request Definition"],"summary":"Create HTTP request definition","description":"Creates a new HTTP request definition. The signing secret is only returned in this response and cannot be retrieved later.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateHttpRequestDefinitionInput"}}}}}},"/v1/http-request-definition/{definitionId}":{"get":{"responses":{"200":{"description":"The requested HTTP request definition","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HttpRequestDefinitionResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Http-request-definitionByDefinitionId","tags":["HTTP Request Definition"],"summary":"Get HTTP request definition by ID","description":"Returns a specific HTTP request definition by its ID.","parameters":[{"name":"definitionId","in":"path","required":true,"description":"The ID of the HTTP request definition to retrieve","schema":{"type":"string"}}]},"put":{"responses":{"200":{"description":"The updated HTTP request definition","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HttpRequestDefinitionResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"putV1Http-request-definitionByDefinitionId","tags":["HTTP Request Definition"],"summary":"Update HTTP request definition","description":"Updates an existing HTTP request definition.","parameters":[{"name":"definitionId","in":"path","required":true,"description":"The ID of the HTTP request definition to update","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHttpRequestDefinitionInput"}}}}}},"/v1/webhook":{"get":{"responses":{"200":{"description":"List of webhooks with their event subscriptions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Webhook","tags":["Webhook"],"summary":"List webhooks","description":"Returns a paginated list of webhooks with their event subscriptions.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20,"description":"Maximum number of webhooks to return (default: 20, max: 50)"}},{"in":"query","name":"after","schema":{"type":"string","description":"Cursor for pagination - webhook ID to start after"}}]},"post":{"responses":{"201":{"description":"The created webhook with signing secret","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CreateWebhookResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Webhook","tags":["Webhook"],"summary":"Create webhook","description":"Creates a new webhook with event subscriptions. The signing secret is only returned in this response.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookInput"}}}}}},"/v1/webhook/{webhookId}":{"get":{"responses":{"200":{"description":"The requested webhook with its event subscriptions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookResponse"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1WebhookByWebhookId","tags":["Webhook"],"summary":"Get webhook by ID","description":"Returns a specific webhook with its event subscriptions.","parameters":[{"name":"webhookId","in":"path","required":true,"description":"The ID of the webhook to retrieve","schema":{"type":"string"}}]},"delete":{"responses":{"200":{"description":"Webhook deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the deletion was successful"}},"required":["success"]}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"deleteV1WebhookByWebhookId","tags":["Webhook"],"summary":"Delete webhook","description":"Deletes a webhook and all its event subscriptions.","parameters":[{"name":"webhookId","in":"path","required":true,"description":"The ID of the webhook to delete","schema":{"type":"string"}}]}},"/v1/issue":{"get":{"responses":{"200":{"description":"List of issues","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Issue"}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"hasMore":{"type":"boolean"}},"required":["limit","offset","hasMore"]}},"required":["data","pagination"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Issue","tags":["Issue"],"summary":"List issues","description":"Returns the project’s issues, ordered newest-first. Supports filtering by status, source, and severity, with offset pagination.","parameters":[{"in":"query","name":"status","schema":{"type":"string","enum":["OPEN","ACKED","RESOLVED"],"description":"Lifecycle state"}},{"in":"query","name":"source","schema":{"type":"string","enum":["TREND_ALERT","SINGLE_CALL_ALERT","TRACE_FAILURE","MANUAL","API","AGENT"],"description":"Who opened the issue"}},{"in":"query","name":"severity","schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Coarse priority — LOW / MEDIUM / HIGH / CRITICAL"}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of issues to return (default: 20, max: 100)"}},{"in":"query","name":"offset","schema":{"type":"integer","minimum":0,"default":0,"description":"Pagination offset"}}]},"post":{"responses":{"201":{"description":"The created issue","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Issue"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Issue","tags":["Issue"],"summary":"Create issue","description":"Opens a new issue with `source: API`. The supplied evidence (calls / chats) is attached in the same transaction; an invalid reference fails the whole request rather than leaving a half-created issue.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueInput"}}}}}},"/v1/issue/{issueId}":{"get":{"responses":{"200":{"description":"The requested issue","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Issue"}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1IssueByIssueId","tags":["Issue"],"summary":"Get issue by ID","description":"Returns a single issue with its evidence rows.","parameters":[{"name":"issueId","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/knowledge-base":{"get":{"responses":{"200":{"description":"A page of knowledge bases.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the knowledge base."},"name":{"type":"string","description":"Customer-supplied name. Unique within the project."},"description":{"type":["string","null"],"description":"Optional customer-supplied description."},"sourceType":{"type":"string","enum":["TEXT","FILE","JSON","URL"],"description":"How the knowledge base content was provided. TEXT/JSON are stored as-is; FILE was uploaded and its text content extracted (PDF → text); URL was scraped from a webpage into markdown."},"status":{"type":"string","enum":["READY","PROCESSING","PENDING_UPLOAD","FAILED"],"description":"Lifecycle of the knowledge base. READY means the content is available to metrics. PROCESSING is set during PDF text extraction. FAILED means extraction errored — see `errorMessage`."},"originalFilename":{"type":["string","null"],"description":"For FILE source: the customer-supplied filename. Null for TEXT/JSON/URL."},"mimeType":{"type":["string","null"],"description":"For FILE source: the mime type of the uploaded file. Null for TEXT/JSON/URL."},"sourceUrl":{"type":["string","null"],"description":"For URL source: the page that was scraped into markdown. Null for TEXT/JSON/FILE."},"byteSize":{"type":"integer","minimum":0,"description":"Size of the content the model will read at evaluation time. For FILE this is the EXTRACTED text size, not the original PDF size."},"contentHash":{"type":["string","null"],"description":"SHA-256 of the content. Stable across whitespace-equivalent edits for JSON (pretty-printed before hashing). Use it to detect change without diffing the content."},"errorMessage":{"type":["string","null"],"description":"When `status` is FAILED, the reason. Null otherwise."},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format."},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format."}},"required":["id","name","description","sourceType","status","originalFilename","mimeType","sourceUrl","byteSize","contentHash","errorMessage","createdAt","updatedAt"],"title":"KnowledgeBase","description":"A customer-uploaded reference document attached to custom metrics as ground truth at evaluation time."}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"hasMore":{"type":"boolean","description":"Whether there are more items to fetch"},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page of items"}},"required":["total","hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Knowledge-base","tags":["Knowledge Base"],"summary":"List knowledge bases","description":"Returns a cursor-paginated list of knowledge bases for the authenticated project. Soft-deleted knowledge bases are excluded.","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"in":"query","name":"after","schema":{"type":"string"}},{"in":"query","name":"searchText","schema":{"type":"string"}},{"in":"query","name":"sourceType","schema":{"type":"string","enum":["TEXT","FILE","JSON","URL"],"description":"How the knowledge base content was provided. TEXT/JSON are stored as-is; FILE was uploaded and its text content extracted (PDF → text); URL was scraped from a webpage into markdown."}}]},"post":{"responses":{"201":{"description":"The created knowledge base.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the knowledge base."},"name":{"type":"string","description":"Customer-supplied name. Unique within the project."},"description":{"type":["string","null"],"description":"Optional customer-supplied description."},"sourceType":{"type":"string","enum":["TEXT","FILE","JSON","URL"],"description":"How the knowledge base content was provided. TEXT/JSON are stored as-is; FILE was uploaded and its text content extracted (PDF → text); URL was scraped from a webpage into markdown."},"status":{"type":"string","enum":["READY","PROCESSING","PENDING_UPLOAD","FAILED"],"description":"Lifecycle of the knowledge base. READY means the content is available to metrics. PROCESSING is set during PDF text extraction. FAILED means extraction errored — see `errorMessage`."},"originalFilename":{"type":["string","null"],"description":"For FILE source: the customer-supplied filename. Null for TEXT/JSON/URL."},"mimeType":{"type":["string","null"],"description":"For FILE source: the mime type of the uploaded file. Null for TEXT/JSON/URL."},"sourceUrl":{"type":["string","null"],"description":"For URL source: the page that was scraped into markdown. Null for TEXT/JSON/FILE."},"byteSize":{"type":"integer","minimum":0,"description":"Size of the content the model will read at evaluation time. For FILE this is the EXTRACTED text size, not the original PDF size."},"contentHash":{"type":["string","null"],"description":"SHA-256 of the content. Stable across whitespace-equivalent edits for JSON (pretty-printed before hashing). Use it to detect change without diffing the content."},"errorMessage":{"type":["string","null"],"description":"When `status` is FAILED, the reason. Null otherwise."},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format."},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format."}},"required":["id","name","description","sourceType","status","originalFilename","mimeType","sourceUrl","byteSize","contentHash","errorMessage","createdAt","updatedAt"],"title":"KnowledgeBase","description":"A customer-uploaded reference document attached to custom metrics as ground truth at evaluation time."}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1Knowledge-base","tags":["Knowledge Base"],"summary":"Create a knowledge base","description":"Creates a knowledge base. TEXT and JSON sources accept inline `content`. FILE sources require `filename`, `mimeType`, and base64-encoded `contentBase64` — the file is decoded server-side, stored in S3, and (for PDFs) text-extracted inline before the response returns.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"Customer-facing name. Unique within the project. Required."},"description":{"type":["string","null"],"maxLength":500,"description":"Optional short blurb shown in pickers."},"sourceType":{"type":"string","enum":["TEXT","FILE","JSON"],"description":"Source types accepted via the public create endpoint. URL ingestion is currently only available in the platform UI."},"content":{"type":["string","null"],"description":"For TEXT: raw markdown/text. For JSON: a JSON string (validated server-side and re-formatted with stable whitespace). Required for TEXT and JSON; omit for FILE."},"filename":{"type":["string","null"],"minLength":1,"maxLength":255,"description":"For FILE: customer-supplied filename (informational only — used for download links)."},"mimeType":{"type":["string","null"],"enum":["application/pdf","text/plain","text/markdown"],"description":"For FILE: mime type of the uploaded file. Only `application/pdf`, `text/plain`, and `text/markdown` are accepted."},"contentBase64":{"type":["string","null"],"description":"For FILE: base64-encoded file bytes. Required for FILE. Max 10 MB after decoding. PDFs are text-extracted server-side; image-only PDFs are rejected."}},"required":["name","sourceType"],"title":"CreateKnowledgeBaseInput","description":"Input for creating a knowledge base. See `sourceType` for which fields are required."}}}}}},"/v1/knowledge-base/{id}":{"get":{"responses":{"200":{"description":"The requested knowledge base.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the knowledge base."},"name":{"type":"string","description":"Customer-supplied name. Unique within the project."},"description":{"type":["string","null"],"description":"Optional customer-supplied description."},"sourceType":{"type":"string","enum":["TEXT","FILE","JSON","URL"],"description":"How the knowledge base content was provided. TEXT/JSON are stored as-is; FILE was uploaded and its text content extracted (PDF → text); URL was scraped from a webpage into markdown."},"status":{"type":"string","enum":["READY","PROCESSING","PENDING_UPLOAD","FAILED"],"description":"Lifecycle of the knowledge base. READY means the content is available to metrics. PROCESSING is set during PDF text extraction. FAILED means extraction errored — see `errorMessage`."},"originalFilename":{"type":["string","null"],"description":"For FILE source: the customer-supplied filename. Null for TEXT/JSON/URL."},"mimeType":{"type":["string","null"],"description":"For FILE source: the mime type of the uploaded file. Null for TEXT/JSON/URL."},"sourceUrl":{"type":["string","null"],"description":"For URL source: the page that was scraped into markdown. Null for TEXT/JSON/FILE."},"byteSize":{"type":"integer","minimum":0,"description":"Size of the content the model will read at evaluation time. For FILE this is the EXTRACTED text size, not the original PDF size."},"contentHash":{"type":["string","null"],"description":"SHA-256 of the content. Stable across whitespace-equivalent edits for JSON (pretty-printed before hashing). Use it to detect change without diffing the content."},"errorMessage":{"type":["string","null"],"description":"When `status` is FAILED, the reason. Null otherwise."},"createdAt":{"type":"string","description":"Creation timestamp in ISO 8601 format."},"updatedAt":{"type":"string","description":"Last update timestamp in ISO 8601 format."}},"required":["id","name","description","sourceType","status","originalFilename","mimeType","sourceUrl","byteSize","contentHash","errorMessage","createdAt","updatedAt"],"title":"KnowledgeBase","description":"A customer-uploaded reference document attached to custom metrics as ground truth at evaluation time."}},"required":["data"]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Not found error"},"example":{"type":"not_found","code":"resource_not_found","message":"The requested resource could not be found"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"getV1Knowledge-baseById","tags":["Knowledge Base"],"summary":"Get a knowledge base by ID","description":"Returns metadata for a single knowledge base. Does not include content — content is read by metrics at evaluation time and is not exposed over the public API.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Knowledge base ID"}]}},"/v1/config/diff":{"post":{"responses":{"200":{"description":"The projected changes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ConfigDiffResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1ConfigDiff","tags":["Config"],"summary":"Diff a config bundle","description":"Dry run for a config-as-code apply: returns the projected changes (create / update / delete) for the submitted bundle without writing anything. Submit the full desired set of resources; identity is by name — no ids in the bundle. Run this before apply to preview what would change.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigBundle"}}}}}},"/v1/config/apply":{"post":{"responses":{"200":{"description":"The applied changes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ConfigApplyResponse"}},"required":["data"]}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Validation error"},"example":{"type":"validation","code":"invalid_parameter","message":"The request was invalid","param":"email"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Authentication error"},"example":{"type":"authentication","code":"unauthorized","message":"Authentication required"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Permission error"},"example":{"type":"forbidden","code":"permission_denied","message":"You do not have permission to access this resource"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Rate limit error"},"example":{"type":"rate_limit","code":"too_many_requests","message":"Rate limit exceeded"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse","description":"Server error"},"example":{"type":"internal","code":"internal_error","message":"Internal server error"}}},"description":"Internal Server Error"}},"operationId":"postV1ConfigApply","tags":["Config"],"summary":"Apply a config bundle","description":"Reconcile a config-as-code bundle into the project. Submit the full desired set of resources; resources already managed by config are updated, new ones created, and (unless prune is false) config-managed resources absent from the bundle are deleted. Identity is by name — no ids in the bundle.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigBundle"}}}}}}}}