diff --git a/specification/DigitalOcean-public.v2.yaml b/specification/DigitalOcean-public.v2.yaml index a26d71aa6..51cb1b467 100644 --- a/specification/DigitalOcean-public.v2.yaml +++ b/specification/DigitalOcean-public.v2.yaml @@ -577,6 +577,18 @@ tags: description: |- Security CSPM endpoints for scans, scan findings, and settings. + - name: Signals + description: |- + The DigitalOcean Signals API provides observability for agent + conversations, such as Harness Runtime sessions and Serverless + Inference chat completions, detecting behavioral signals such as + user disengagement, execution failures, and satisfaction indicators. + + Use the consent endpoints to manage whether signals collection is + enabled for each agent, the session endpoints to browse agent + conversations and their detected signals, and the export endpoints + to create downloadable archives of signals data for offline analysis. + - name: Sizes description: |- The sizes objects represent different packages of hardware resources that @@ -754,6 +766,7 @@ x-tagGroups: - Reserved IPv6 - Reserved IPv6 Actions - Security + - Signals - Sizes - Snapshots - Spaces Keys @@ -1827,6 +1840,44 @@ paths: post: $ref: "resources/insights/insights_post_logsSearch.yml" + /v1/consent: + get: + $ref: "resources/signals/signals_list_consents.yml" + + /v1/consent/{agent_id}: + get: + $ref: "resources/signals/signals_get_consent.yml" + + put: + $ref: "resources/signals/signals_update_consent.yml" + + /v1/signals/agents/{agent_id}/sessions: + get: + $ref: "resources/signals/signals_list_sessions.yml" + + /v1/signals/sessions/{session_id}/dialogues: + get: + $ref: "resources/signals/signals_list_dialogues.yml" + + /v1/signals/exports: + get: + $ref: "resources/signals/signals_list_exports.yml" + + post: + $ref: "resources/signals/signals_create_export.yml" + + /v1/signals/exports/options: + get: + $ref: "resources/signals/signals_get_export_options.yml" + + /v1/signals/exports/{export_id}: + get: + $ref: "resources/signals/signals_get_export.yml" + + /v1/signals/exports/{export_id}/download: + get: + $ref: "resources/signals/signals_get_export_download.yml" + /v2/kubernetes/clusters: get: $ref: "resources/kubernetes/kubernetes_list_clusters.yml" diff --git a/specification/resources/signals/examples/curl/signals_create_export.yml b/specification/resources/signals/examples/curl/signals_create_export.yml new file mode 100644 index 000000000..b99a68d39 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_create_export.yml @@ -0,0 +1,7 @@ +lang: cURL +source: |- + curl -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -d '{"agent_id":"01a0f3d5-b58d-7c99-a743-7ca0397b7f5d","signal_type":["ExecutionFailureToolNotFound"]}' \ + "https://api.digitalocean.com/v1/signals/exports" diff --git a/specification/resources/signals/examples/curl/signals_get_consent.yml b/specification/resources/signals/examples/curl/signals_get_consent.yml new file mode 100644 index 000000000..f2bded985 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_get_consent.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/consent/019fb3d2-8a56-72cc-8bf9-9d21510b2a99" diff --git a/specification/resources/signals/examples/curl/signals_get_export.yml b/specification/resources/signals/examples/curl/signals_get_export.yml new file mode 100644 index 000000000..c9e83853d --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_get_export.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/exports/9f13c09c-c877-436b-9863-dcc39c9dd737" diff --git a/specification/resources/signals/examples/curl/signals_get_export_download.yml b/specification/resources/signals/examples/curl/signals_get_export_download.yml new file mode 100644 index 000000000..04e84a621 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_get_export_download.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/exports/9f13c09c-c877-436b-9863-dcc39c9dd737/download" diff --git a/specification/resources/signals/examples/curl/signals_get_export_options.yml b/specification/resources/signals/examples/curl/signals_get_export_options.yml new file mode 100644 index 000000000..0e895034c --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_get_export_options.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/exports/options" diff --git a/specification/resources/signals/examples/curl/signals_list_consents.yml b/specification/resources/signals/examples/curl/signals_list_consents.yml new file mode 100644 index 000000000..aa7637298 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_list_consents.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/consent" diff --git a/specification/resources/signals/examples/curl/signals_list_dialogues.yml b/specification/resources/signals/examples/curl/signals_list_dialogues.yml new file mode 100644 index 000000000..c39f0ef7f --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_list_dialogues.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/sessions/01a0f3d5-d5f1-798a-9352-2cd8f8b81e78/dialogues?limit=20" diff --git a/specification/resources/signals/examples/curl/signals_list_exports.yml b/specification/resources/signals/examples/curl/signals_list_exports.yml new file mode 100644 index 000000000..1478c23d2 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_list_exports.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/exports?limit=20" diff --git a/specification/resources/signals/examples/curl/signals_list_sessions.yml b/specification/resources/signals/examples/curl/signals_list_sessions.yml new file mode 100644 index 000000000..35ba2ffe9 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_list_sessions.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/agents/019fb3d2-8a56-72cc-8bf9-9d21510b2a99/sessions?limit=20" diff --git a/specification/resources/signals/examples/curl/signals_update_consent.yml b/specification/resources/signals/examples/curl/signals_update_consent.yml new file mode 100644 index 000000000..a74162ec4 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_update_consent.yml @@ -0,0 +1,7 @@ +lang: cURL +source: |- + curl -X PUT \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -d '{"enabled":true}' \ + "https://api.digitalocean.com/v1/consent/019fb3d2-8a56-72cc-8bf9-9d21510b2a99" diff --git a/specification/resources/signals/models/agent_consent.yml b/specification/resources/signals/models/agent_consent.yml new file mode 100644 index 000000000..a315c6278 --- /dev/null +++ b/specification/resources/signals/models/agent_consent.yml @@ -0,0 +1,38 @@ +type: object +description: Consent details for a specific agent, including an allowed flag. +properties: + id: + type: integer + description: The unique numeric identifier for the consent record. + example: 13 + team_id: + type: integer + description: The team ID that owns this consent record. + example: 39449946 + agent_id: + type: string + format: uuid + description: The unique identifier of the agent. For Harness Runtime, this is the Environment Config ID. + example: 019fb3d2-8a56-72cc-8bf9-9d21510b2a99 + enabled: + type: boolean + description: Whether signals collection is enabled for this agent. + example: true + allowed: + type: boolean + description: >- + Whether the team is permitted to use signals for this agent. This is + determined by the platform and cannot be set by the user. + example: true + updated_at: + type: string + format: date-time + description: A time value given in ISO8601 combined date and time format. + example: "2026-08-10T10:09:25.738533Z" +required: + - id + - team_id + - agent_id + - enabled + - allowed + - updated_at diff --git a/specification/resources/signals/models/consent_record.yml b/specification/resources/signals/models/consent_record.yml new file mode 100644 index 000000000..656c43297 --- /dev/null +++ b/specification/resources/signals/models/consent_record.yml @@ -0,0 +1,31 @@ +type: object +description: A consent record indicating whether signals collection is enabled for an agent. +properties: + id: + type: integer + description: The unique numeric identifier for the consent record. + example: 13 + team_id: + type: integer + description: The team ID that owns this consent record. + example: 39449946 + agent_id: + type: string + format: uuid + description: The unique identifier of the agent. For Harness Runtime, this is the Environment Config ID. + example: 019fb3d2-8a56-72cc-8bf9-9d21510b2a99 + enabled: + type: boolean + description: Whether signals collection is enabled for this agent. + example: true + updated_at: + type: string + format: date-time + description: A time value given in ISO8601 combined date and time format. + example: "2026-08-10T10:09:25.738533Z" +required: + - id + - team_id + - agent_id + - enabled + - updated_at diff --git a/specification/resources/signals/models/create_export_request.yml b/specification/resources/signals/models/create_export_request.yml new file mode 100644 index 000000000..1feffdab7 --- /dev/null +++ b/specification/resources/signals/models/create_export_request.yml @@ -0,0 +1,37 @@ +type: object +description: Request body to create a new signals data export. +properties: + agent_id: + type: string + format: uuid + description: The agent whose data should be exported. For Harness Runtime, this is the Environment Config ID. + example: 01a0f3d5-b58d-7c99-a743-7ca0397b7f5d + signal_type: + type: array + items: + type: string + description: >- + Filter the export to only include the specified signal types. Use the + export options endpoint to list available values. + example: + - ExecutionFailureToolNotFound + session_ids: + type: array + description: Optional list of specific session IDs to include in the export. + items: + type: string + format: uuid + example: + - 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + start_time: + type: string + format: date-time + description: Include only sessions that started at or after this timestamp. + example: "2026-09-01T00:00:00Z" + end_time: + type: string + format: date-time + description: Include only sessions that started at or before this timestamp. + example: "2026-10-01T00:00:00Z" +required: + - agent_id diff --git a/specification/resources/signals/models/export_download.yml b/specification/resources/signals/models/export_download.yml new file mode 100644 index 000000000..ad52261ed --- /dev/null +++ b/specification/resources/signals/models/export_download.yml @@ -0,0 +1,15 @@ +type: object +description: A pre-signed download URL for a completed export. +properties: + download_url: + type: string + format: uri + description: A temporary pre-signed URL to download the export archive. + example: "https://example-bucket.nyc3.digitaloceanspaces.com/exports/3f2a1c4e-5b6d-4e7f-8a9b-0c1d2e3f4a5b/9f13c09c-c877-436b-9863-dcc39c9dd737.json.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=EXAMPLE" + expires_at: + type: integer + description: Unix timestamp when the download URL expires. The URL is valid for 15 minutes. + example: 1791390640 +required: + - download_url + - expires_at diff --git a/specification/resources/signals/models/export_job.yml b/specification/resources/signals/models/export_job.yml new file mode 100644 index 000000000..48b978c23 --- /dev/null +++ b/specification/resources/signals/models/export_job.yml @@ -0,0 +1,64 @@ +type: object +description: An export job that produces a downloadable archive of signals data. +properties: + export_id: + type: string + format: uuid + description: The unique identifier for the export job. + example: 9f13c09c-c877-436b-9863-dcc39c9dd737 + agent_id: + type: string + format: uuid + description: The agent whose data is being exported. For Harness Runtime, this is the Environment Config ID. + example: 01a0f3d5-b58d-7c99-a743-7ca0397b7f5d + status: + type: string + description: The current status of the export job. + enum: + - pending + - processing + - complete + - failed + example: complete + filters: + type: object + description: The filters applied to this export. + properties: + signal_type: + type: array + items: + type: string + description: Signal types included in the export. + example: + - ExecutionFailureToolNotFound + session_ids: + type: array + items: + type: string + description: Specific session IDs included in the export. + example: + - 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + created_at: + type: integer + description: Unix timestamp when the export was created. + example: 1791036405 + completed_at: + type: integer + nullable: true + description: Unix timestamp when the export completed, or null if still in progress. + example: 1791036405 + expires_at: + type: integer + nullable: true + description: Unix timestamp when the export download link expires. + example: 1791641205 + error_message: + type: string + nullable: true + description: Error message if the export failed, or null on success. + example: null +required: + - export_id + - agent_id + - status + - created_at diff --git a/specification/resources/signals/models/export_options.yml b/specification/resources/signals/models/export_options.yml new file mode 100644 index 000000000..8f1d303d3 --- /dev/null +++ b/specification/resources/signals/models/export_options.yml @@ -0,0 +1,28 @@ +type: object +description: Available filter options for creating exports. +properties: + filters: + type: object + properties: + signal_type: + type: array + description: The list of valid signal type values that can be used when creating an export. + items: + type: string + example: + - DisengagementEscalation + - DisengagementNegativeStance + - DisengagementQuit + - EnvironmentExhaustionApiError + - EnvironmentExhaustionContextOverflow + - ExecutionFailureToolNotFound + - ExecutionLoopsRetry + - MisalignmentCorrection + - SatisfactionConfirmation + - SatisfactionGratitude + - SatisfactionSuccess + - StagnationRepetition + required: + - signal_type +required: + - filters diff --git a/specification/resources/signals/models/list_consents.yml b/specification/resources/signals/models/list_consents.yml new file mode 100644 index 000000000..e0596bc86 --- /dev/null +++ b/specification/resources/signals/models/list_consents.yml @@ -0,0 +1,10 @@ +type: object +description: A wrapper for a list of consent records. +properties: + consents: + type: array + description: A list of consent records for the team's agents. + items: + $ref: 'consent_record.yml' +required: + - consents diff --git a/specification/resources/signals/models/session.yml b/specification/resources/signals/models/session.yml new file mode 100644 index 000000000..af4a7b75e --- /dev/null +++ b/specification/resources/signals/models/session.yml @@ -0,0 +1,27 @@ +type: object +description: A session represents a conversation monitored by Signals, such as a Harness Runtime agent session or a Serverless Inference chat completion. +properties: + session_id: + type: string + format: uuid + description: The unique identifier for the session. + example: 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + total_turns: + type: integer + description: The total number of conversation turns in this session. + example: 5 + started_at: + type: string + format: date-time + description: When the session started. + example: "2026-09-15T14:30:00Z" + duration_seconds: + type: number + description: The duration of the session in seconds. + example: 120.5 + signal_count: + type: integer + description: The number of signals detected in this session. + example: 3 +required: + - session_id diff --git a/specification/resources/signals/models/session_dialogue.yml b/specification/resources/signals/models/session_dialogue.yml new file mode 100644 index 000000000..928cd3345 --- /dev/null +++ b/specification/resources/signals/models/session_dialogue.yml @@ -0,0 +1,28 @@ +type: object +description: A dialogue entry within a session, representing a single turn of conversation. +properties: + id: + type: string + description: The unique identifier for the dialogue. + example: "01a0f3d6-1234-7abc-def0-123456789abc" + sequence: + type: integer + description: The sequence number of this dialogue within the session. + example: 1 + run_status: + type: string + description: The execution status of this dialogue turn. + example: completed + user_message: + type: string + description: The user's message in this dialogue turn. + example: "How do I create a Droplet?" + signals: + type: array + description: A list of signal types detected in this dialogue. + items: + type: string + example: + - SatisfactionConfirmation +required: + - id diff --git a/specification/resources/signals/parameters.yml b/specification/resources/signals/parameters.yml new file mode 100644 index 000000000..30fd3db09 --- /dev/null +++ b/specification/resources/signals/parameters.yml @@ -0,0 +1,85 @@ +agent_id: + in: path + name: agent_id + description: A unique identifier for an agent. For Harness Runtime, this is the Environment Config ID. + required: true + schema: + type: string + format: uuid + example: 019fb3d2-8a56-72cc-8bf9-9d21510b2a99 + +session_id: + in: path + name: session_id + description: A unique identifier for a signals session. + required: true + schema: + type: string + format: uuid + example: 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + +export_id: + in: path + name: export_id + description: A unique identifier for an export job. + required: true + schema: + type: string + format: uuid + example: 9f13c09c-c877-436b-9863-dcc39c9dd737 + +limit: + in: query + name: limit + description: Maximum number of items to return per page. + required: false + schema: + type: integer + minimum: 1 + maximum: 100 + default: 20 + example: 20 + +after: + in: query + name: after + description: >- + An opaque cursor string returned from a previous page. Pass this value to + retrieve the next page of results. + required: false + schema: + type: string + example: eyJ0ZWFtX2lkIjozOTQ0OTk0Nn0= + +signal_type: + in: query + name: signal_type + description: >- + Filter results by signal type. Use the export options endpoint to list + available signal types. + required: false + schema: + type: string + example: DisengagementEscalation + +start_time: + in: query + name: start_time + description: >- + Filter results to those occurring at or after this timestamp (RFC 3339). + required: false + schema: + type: string + format: date-time + example: "2026-09-01T00:00:00Z" + +end_time: + in: query + name: end_time + description: >- + Filter results to those occurring at or before this timestamp (RFC 3339). + required: false + schema: + type: string + format: date-time + example: "2026-10-01T00:00:00Z" diff --git a/specification/resources/signals/responses/agent_consent_response.yml b/specification/resources/signals/responses/agent_consent_response.yml new file mode 100644 index 000000000..8e35c5f51 --- /dev/null +++ b/specification/resources/signals/responses/agent_consent_response.yml @@ -0,0 +1,21 @@ +description: A single agent consent record. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + $ref: '../models/agent_consent.yml' + example: + id: 13 + team_id: 39449946 + agent_id: 019fb3d2-8a56-72cc-8bf9-9d21510b2a99 + enabled: true + allowed: true + updated_at: "2026-08-10T10:09:25.738533Z" diff --git a/specification/resources/signals/responses/export_download_response.yml b/specification/resources/signals/responses/export_download_response.yml new file mode 100644 index 000000000..e9a450ff8 --- /dev/null +++ b/specification/resources/signals/responses/export_download_response.yml @@ -0,0 +1,17 @@ +description: A download URL for a completed export. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + $ref: '../models/export_download.yml' + example: + download_url: "https://example-bucket.nyc3.digitaloceanspaces.com/exports/3f2a1c4e-5b6d-4e7f-8a9b-0c1d2e3f4a5b/9f13c09c-c877-436b-9863-dcc39c9dd737.json.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=EXAMPLE" + expires_at: 1791390640 diff --git a/specification/resources/signals/responses/export_job_response.yml b/specification/resources/signals/responses/export_job_response.yml new file mode 100644 index 000000000..ada9e3a19 --- /dev/null +++ b/specification/resources/signals/responses/export_job_response.yml @@ -0,0 +1,27 @@ +description: A single export job. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + $ref: '../models/export_job.yml' + example: + export_id: 9f13c09c-c877-436b-9863-dcc39c9dd737 + agent_id: 01a0f3d5-b58d-7c99-a743-7ca0397b7f5d + status: complete + filters: + signal_type: + - ExecutionFailureToolNotFound + session_ids: + - 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + created_at: 1791036405 + completed_at: 1791036405 + expires_at: 1791641205 + error_message: null diff --git a/specification/resources/signals/responses/export_options_response.yml b/specification/resources/signals/responses/export_options_response.yml new file mode 100644 index 000000000..5c8ebfb40 --- /dev/null +++ b/specification/resources/signals/responses/export_options_response.yml @@ -0,0 +1,28 @@ +description: Available export filter options. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + $ref: '../models/export_options.yml' + example: + filters: + signal_type: + - DisengagementEscalation + - DisengagementNegativeStance + - DisengagementQuit + - EnvironmentExhaustionApiError + - ExecutionFailureToolNotFound + - ExecutionLoopsRetry + - MisalignmentCorrection + - SatisfactionConfirmation + - SatisfactionGratitude + - SatisfactionSuccess + - StagnationRepetition diff --git a/specification/resources/signals/responses/list_consents_response.yml b/specification/resources/signals/responses/list_consents_response.yml new file mode 100644 index 000000000..98b5a1bc8 --- /dev/null +++ b/specification/resources/signals/responses/list_consents_response.yml @@ -0,0 +1,26 @@ +description: A list of consent records. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + $ref: '../models/list_consents.yml' + example: + consents: + - id: 13 + team_id: 39449946 + agent_id: 019fb3d2-8a56-72cc-8bf9-9d21510b2a99 + enabled: true + updated_at: "2026-08-10T10:09:25.738533Z" + - id: 6 + team_id: 39449946 + agent_id: 019fb6b1-aad4-7d54-a74e-c5570d768148 + enabled: true + updated_at: "2026-08-07T10:10:16.385447Z" diff --git a/specification/resources/signals/responses/list_dialogues_response.yml b/specification/resources/signals/responses/list_dialogues_response.yml new file mode 100644 index 000000000..d188c67f7 --- /dev/null +++ b/specification/resources/signals/responses/list_dialogues_response.yml @@ -0,0 +1,44 @@ +description: A paginated list of session dialogues. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + type: object + properties: + edges: + type: array + items: + type: object + properties: + cursor: + type: string + description: An opaque cursor for pagination. + example: eyJzZXF1ZW5jZSI6MX0= + node: + $ref: '../models/session_dialogue.yml' + page_info: + type: object + properties: + has_next_page: + type: boolean + description: Whether there are more results after this page. + example: + edges: + - cursor: eyJzZXF1ZW5jZSI6MX0= + node: + id: "01a0f3d6-1234-7abc-def0-123456789abc" + sequence: 1 + run_status: completed + user_message: "How do I create a Droplet?" + signals: + - SatisfactionConfirmation + page_info: + has_next_page: false diff --git a/specification/resources/signals/responses/list_exports_response.yml b/specification/resources/signals/responses/list_exports_response.yml new file mode 100644 index 000000000..92c494b04 --- /dev/null +++ b/specification/resources/signals/responses/list_exports_response.yml @@ -0,0 +1,50 @@ +description: A paginated list of export jobs. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + type: object + properties: + edges: + type: array + items: + type: object + properties: + cursor: + type: string + description: An opaque cursor for pagination. + example: eyJ0ZWFtX2lkIjozOTQ0OTk0Nn0= + node: + $ref: '../models/export_job.yml' + page_info: + type: object + properties: + has_next_page: + type: boolean + description: Whether there are more results after this page. + example: + edges: + - cursor: eyJ0ZWFtX2lkIjozOTQ0OTk0Nn0= + node: + export_id: 9f13c09c-c877-436b-9863-dcc39c9dd737 + agent_id: 01a0f3d5-b58d-7c99-a743-7ca0397b7f5d + status: complete + filters: + signal_type: + - ExecutionFailureToolNotFound + session_ids: + - 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + created_at: 1791036405 + completed_at: 1791036405 + expires_at: 1791641205 + error_message: null + page_info: + has_next_page: false diff --git a/specification/resources/signals/responses/list_sessions_response.yml b/specification/resources/signals/responses/list_sessions_response.yml new file mode 100644 index 000000000..c89c84e70 --- /dev/null +++ b/specification/resources/signals/responses/list_sessions_response.yml @@ -0,0 +1,43 @@ +description: A paginated list of sessions. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + type: object + properties: + edges: + type: array + items: + type: object + properties: + cursor: + type: string + description: An opaque cursor for pagination. + example: eyJ0ZWFtX2lkIjozOTQ0OTk0Nn0= + node: + $ref: '../models/session.yml' + page_info: + type: object + properties: + has_next_page: + type: boolean + description: Whether there are more results after this page. + example: + edges: + - cursor: eyJ0ZWFtX2lkIjozOTQ0OTk0Nn0= + node: + session_id: 01a0f3d5-d5f1-798a-9352-2cd8f8b81e78 + total_turns: 5 + started_at: "2026-09-15T14:30:00Z" + duration_seconds: 120.5 + signal_count: 3 + page_info: + has_next_page: false diff --git a/specification/resources/signals/responses/update_consent_response.yml b/specification/resources/signals/responses/update_consent_response.yml new file mode 100644 index 000000000..0717d27ec --- /dev/null +++ b/specification/resources/signals/responses/update_consent_response.yml @@ -0,0 +1,26 @@ +description: The consent record was updated successfully. + +headers: + ratelimit-limit: + $ref: '../../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../../shared/headers.yml#/ratelimit-reset' + +content: + application/json: + schema: + type: object + properties: + consent: + $ref: '../models/consent_record.yml' + required: + - consent + example: + consent: + id: 13 + team_id: 39449946 + agent_id: 019fb3d2-8a56-72cc-8bf9-9d21510b2a99 + enabled: true + updated_at: "2026-10-07T11:06:32.280572Z" diff --git a/specification/resources/signals/signals_create_export.yml b/specification/resources/signals/signals_create_export.yml new file mode 100644 index 000000000..89b2f74b7 --- /dev/null +++ b/specification/resources/signals/signals_create_export.yml @@ -0,0 +1,57 @@ +operationId: signals_create_export + +summary: Create an Export Job + +description: | + To create a new signals data export, send a POST request to + `/v1/signals/exports` with an `agent_id` in the request body. You may + optionally filter the export by `signal_type`, `session_ids`, `start_time`, + and `end_time`. Use the export options endpoint to discover available signal + types. + + The export job runs asynchronously. Poll the get export endpoint to check + its status. When complete, use the download endpoint to retrieve a + pre-signed URL. + +tags: + - Signals + +requestBody: + required: true + content: + application/json: + schema: + $ref: 'models/create_export_request.yml' + example: + agent_id: 01a0f3d5-b58d-7c99-a743-7ca0397b7f5d + signal_type: + - ExecutionFailureToolNotFound + +responses: + '201': + $ref: 'responses/export_job_response.yml' + + '400': + $ref: '../../shared/responses/bad_request.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '422': + $ref: '../../shared/responses/unprocessable_entity.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_create_export.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_get_consent.yml b/specification/resources/signals/signals_get_consent.yml new file mode 100644 index 000000000..029e11a18 --- /dev/null +++ b/specification/resources/signals/signals_get_consent.yml @@ -0,0 +1,40 @@ +operationId: signals_get_consent + +summary: Retrieve Consent for an Agent + +description: | + To retrieve the consent record for a specific agent, send a GET + request to `/v1/consent/{agent_id}`. The response includes an `allowed` + field indicating whether the team is permitted to use signals for this agent. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/agent_id' + +responses: + '200': + $ref: 'responses/agent_consent_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '404': + $ref: '../../shared/responses/not_found.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_get_consent.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_get_export.yml b/specification/resources/signals/signals_get_export.yml new file mode 100644 index 000000000..e1f1e8f00 --- /dev/null +++ b/specification/resources/signals/signals_get_export.yml @@ -0,0 +1,39 @@ +operationId: signals_get_export + +summary: Retrieve an Export Job + +description: | + To retrieve the status and details of a signals export job, send a GET + request to `/v1/signals/exports/{export_id}`. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/export_id' + +responses: + '200': + $ref: 'responses/export_job_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '404': + $ref: '../../shared/responses/not_found.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_get_export.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_get_export_download.yml b/specification/resources/signals/signals_get_export_download.yml new file mode 100644 index 000000000..adc3137d5 --- /dev/null +++ b/specification/resources/signals/signals_get_export_download.yml @@ -0,0 +1,40 @@ +operationId: signals_get_export_download + +summary: Get Export Download URL + +description: | + To retrieve a pre-signed download URL for a completed export, send a GET + request to `/v1/signals/exports/{export_id}/download`. The export must have + a `complete` status. The URL is temporary and will expire. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/export_id' + +responses: + '200': + $ref: 'responses/export_download_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '404': + $ref: '../../shared/responses/not_found.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_get_export_download.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_get_export_options.yml b/specification/resources/signals/signals_get_export_options.yml new file mode 100644 index 000000000..6ee7cf844 --- /dev/null +++ b/specification/resources/signals/signals_get_export_options.yml @@ -0,0 +1,34 @@ +operationId: signals_get_export_options + +summary: Get Export Options + +description: | + To retrieve the available filter options for creating an export, send a GET + request to `/v1/signals/exports/options`. The response lists valid signal + types that can be used in the `signal_type` filter when creating an export. + +tags: + - Signals + +responses: + '200': + $ref: 'responses/export_options_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_get_export_options.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_list_consents.yml b/specification/resources/signals/signals_list_consents.yml new file mode 100644 index 000000000..f2590c200 --- /dev/null +++ b/specification/resources/signals/signals_list_consents.yml @@ -0,0 +1,34 @@ +operationId: signals_list_consents + +summary: List All Consent Records + +description: | + To list all signals consent records for your team, send a GET request to + `/v1/consent`. Each record indicates whether signals collection is enabled + for a specific agent. + +tags: + - Signals + +responses: + '200': + $ref: 'responses/list_consents_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_list_consents.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_list_dialogues.yml b/specification/resources/signals/signals_list_dialogues.yml new file mode 100644 index 000000000..aed5013c5 --- /dev/null +++ b/specification/resources/signals/signals_list_dialogues.yml @@ -0,0 +1,46 @@ +operationId: signals_list_session_dialogues + +summary: List Dialogues for a Session + +description: | + To list the dialogue turns within a specific session, send a GET request to + `/v1/signals/sessions/{session_id}/dialogues`. Each dialogue represents a + single turn of conversation between a user and the agent, along with + any signals detected. Results are paginated using cursor-based pagination. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/session_id' + - $ref: 'parameters.yml#/limit' + - $ref: 'parameters.yml#/after' + - $ref: 'parameters.yml#/start_time' + - $ref: 'parameters.yml#/end_time' + - $ref: 'parameters.yml#/signal_type' + +responses: + '200': + $ref: 'responses/list_dialogues_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '404': + $ref: '../../shared/responses/not_found.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_list_dialogues.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_list_exports.yml b/specification/resources/signals/signals_list_exports.yml new file mode 100644 index 000000000..fbf85311a --- /dev/null +++ b/specification/resources/signals/signals_list_exports.yml @@ -0,0 +1,38 @@ +operationId: signals_list_exports + +summary: List Export Jobs + +description: | + To list signals export jobs for your team, send a GET request to + `/v1/signals/exports`. Results are paginated using cursor-based pagination + with `limit` and `after` parameters. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/limit' + - $ref: 'parameters.yml#/after' + +responses: + '200': + $ref: 'responses/list_exports_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_list_exports.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_list_sessions.yml b/specification/resources/signals/signals_list_sessions.yml new file mode 100644 index 000000000..c0bd6974f --- /dev/null +++ b/specification/resources/signals/signals_list_sessions.yml @@ -0,0 +1,45 @@ +operationId: signals_list_agent_sessions + +summary: List Sessions for an Agent + +description: | + To list signals sessions for a specific agent, send a GET request to + `/v1/signals/agents/{agent_id}/sessions`. Results are paginated using cursor-based + pagination with `limit` and `after` parameters. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/agent_id' + - $ref: 'parameters.yml#/limit' + - $ref: 'parameters.yml#/after' + - $ref: 'parameters.yml#/start_time' + - $ref: 'parameters.yml#/end_time' + - $ref: 'parameters.yml#/signal_type' + +responses: + '200': + $ref: 'responses/list_sessions_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '404': + $ref: '../../shared/responses/not_found.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_list_sessions.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_update_consent.yml b/specification/resources/signals/signals_update_consent.yml new file mode 100644 index 000000000..5ad429a07 --- /dev/null +++ b/specification/resources/signals/signals_update_consent.yml @@ -0,0 +1,55 @@ +operationId: signals_update_consent + +summary: Update Consent for an Agent + +description: | + To enable or disable signals collection for a specific agent, send a + PUT request to `/v1/consent/{agent_id}` with an `enabled` boolean in the + request body. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/agent_id' + +requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: Whether to enable signals collection for this agent. + required: + - enabled + example: + enabled: true + +responses: + '200': + $ref: 'responses/update_consent_response.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '404': + $ref: '../../shared/responses/not_found.yml' + + '429': + $ref: '../../shared/responses/too_many_requests.yml' + + '500': + $ref: '../../shared/responses/server_error.yml' + + default: + $ref: '../../shared/responses/unexpected_error.yml' + +x-codeSamples: + - $ref: 'examples/curl/signals_update_consent.yml' + +security: + - bearer_auth: + - 'signals:update'