From 79a0db4413f4ab51df985d9f799f78791952d4f6 Mon Sep 17 00:00:00 2001 From: Satyam Date: Fri, 9 Oct 2026 16:44:29 +0530 Subject: [PATCH 1/4] Add Signals data deletion endpoints to OpenAPI spec (FI-609) Document the three Signals data deletion endpoints: - POST /v1/signals/deletions (create deletion job) - GET /v1/signals/deletions (list deletion jobs) - GET /v1/signals/deletions/{deletion_id} (get deletion job) Create returns 202 for a new job and 200 when an active job for the same target is reused. type and team_id are required; agent_id is required for managed_agent and must be omitted for inference. Create requires the signals:delete scope; get and list use signals:read. Co-authored-by: Cursor --- specification/DigitalOcean-public.v2.yaml | 16 +++- .../examples/curl/signals_create_deletion.yml | 7 ++ .../examples/curl/signals_get_deletion.yml | 5 ++ .../examples/curl/signals_list_deletions.yml | 5 ++ .../models/create_deletion_request.yml | 30 +++++++ .../resources/signals/models/deletion_job.yml | 76 +++++++++++++++++ .../resources/signals/parameters.yml | 9 +++ .../deletion_job_accepted_response.yml | 26 ++++++ .../responses/deletion_job_response.yml | 24 ++++++ .../responses/list_deletions_response.yml | 64 +++++++++++++++ .../signals/signals_create_deletion.yml | 81 +++++++++++++++++++ .../signals/signals_get_deletion.yml | 39 +++++++++ .../signals/signals_list_deletions.yml | 43 ++++++++++ 13 files changed, 423 insertions(+), 2 deletions(-) create mode 100644 specification/resources/signals/examples/curl/signals_create_deletion.yml create mode 100644 specification/resources/signals/examples/curl/signals_get_deletion.yml create mode 100644 specification/resources/signals/examples/curl/signals_list_deletions.yml create mode 100644 specification/resources/signals/models/create_deletion_request.yml create mode 100644 specification/resources/signals/models/deletion_job.yml create mode 100644 specification/resources/signals/responses/deletion_job_accepted_response.yml create mode 100644 specification/resources/signals/responses/deletion_job_response.yml create mode 100644 specification/resources/signals/responses/list_deletions_response.yml create mode 100644 specification/resources/signals/signals_create_deletion.yml create mode 100644 specification/resources/signals/signals_get_deletion.yml create mode 100644 specification/resources/signals/signals_list_deletions.yml diff --git a/specification/DigitalOcean-public.v2.yaml b/specification/DigitalOcean-public.v2.yaml index 51cb1b467..02109fe37 100644 --- a/specification/DigitalOcean-public.v2.yaml +++ b/specification/DigitalOcean-public.v2.yaml @@ -586,8 +586,9 @@ tags: 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. + conversations and their detected signals, the export endpoints + to create downloadable archives of signals data for offline analysis, + and the deletion endpoints to permanently delete signals data. - name: Sizes description: |- @@ -1878,6 +1879,17 @@ paths: get: $ref: "resources/signals/signals_get_export_download.yml" + /v1/signals/deletions: + get: + $ref: "resources/signals/signals_list_deletions.yml" + + post: + $ref: "resources/signals/signals_create_deletion.yml" + + /v1/signals/deletions/{deletion_id}: + get: + $ref: "resources/signals/signals_get_deletion.yml" + /v2/kubernetes/clusters: get: $ref: "resources/kubernetes/kubernetes_list_clusters.yml" diff --git a/specification/resources/signals/examples/curl/signals_create_deletion.yml b/specification/resources/signals/examples/curl/signals_create_deletion.yml new file mode 100644 index 000000000..522f3617b --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_create_deletion.yml @@ -0,0 +1,7 @@ +lang: cURL +source: |- + curl -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -d '{"type":"managed_agent","team_id":12345678,"agent_id":"01a10d3f-2c09-764f-99f8-458e521627f3"}' \ + "https://api.digitalocean.com/v1/signals/deletions" diff --git a/specification/resources/signals/examples/curl/signals_get_deletion.yml b/specification/resources/signals/examples/curl/signals_get_deletion.yml new file mode 100644 index 000000000..1b28c9245 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_get_deletion.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/deletions/01J9ZX0N5Q7M2K3R4S5T6V7W8X" diff --git a/specification/resources/signals/examples/curl/signals_list_deletions.yml b/specification/resources/signals/examples/curl/signals_list_deletions.yml new file mode 100644 index 000000000..103a18c05 --- /dev/null +++ b/specification/resources/signals/examples/curl/signals_list_deletions.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v1/signals/deletions?limit=20" diff --git a/specification/resources/signals/models/create_deletion_request.yml b/specification/resources/signals/models/create_deletion_request.yml new file mode 100644 index 000000000..4e4f5269c --- /dev/null +++ b/specification/resources/signals/models/create_deletion_request.yml @@ -0,0 +1,30 @@ +type: object +description: Request body to create a new signals data deletion job. +properties: + type: + type: string + description: >- + The scope of the deletion. `managed_agent` deletes all signals data for + one managed agent and requires `agent_id`. `inference` deletes all + signals data from the team's inference (non-agent) usage and must not + include `agent_id`. + enum: + - managed_agent + - inference + example: managed_agent + team_id: + type: integer + format: int64 + description: The team whose data should be deleted. Must match the team of the authenticated token. + example: 12345678 + agent_id: + type: string + format: uuid + description: >- + The managed agent whose data should be deleted. Required when `type` is + `managed_agent`; must be omitted when `type` is `inference`. + example: 01a10d3f-2c09-764f-99f8-458e521627f3 +required: + - type + - team_id +additionalProperties: false diff --git a/specification/resources/signals/models/deletion_job.yml b/specification/resources/signals/models/deletion_job.yml new file mode 100644 index 000000000..e917a5984 --- /dev/null +++ b/specification/resources/signals/models/deletion_job.yml @@ -0,0 +1,76 @@ +type: object +description: >- + A data deletion job that permanently removes signals data for a managed + agent or for a team's inference usage. +properties: + team_id: + type: integer + format: int64 + description: The team that owns the deletion job. + example: 12345678 + deletion_id: + type: string + description: The unique identifier for the deletion job. + example: 01J9ZX0N5Q7M2K3R4S5T6V7W8X + type: + type: string + description: >- + The scope of the deletion. `managed_agent` deletes all signals data for + one managed agent. `inference` deletes all signals data from the team's + inference (non-agent) usage. + enum: + - managed_agent + - inference + example: managed_agent + agent_id: + type: string + format: uuid + description: >- + The managed agent whose data is being deleted. Only present for + `managed_agent` deletions. + example: 01a10d3f-2c09-764f-99f8-458e521627f3 + status: + type: string + description: >- + The current status of the deletion job. `queued` jobs are waiting to be + processed, `running` jobs are actively deleting data, `complete` jobs + have permanently deleted all matching data, and `failed` jobs stopped + with an error described in `error_message`. + enum: + - queued + - running + - complete + - failed + example: running + error_message: + type: string + nullable: true + description: Error message if the deletion failed, or null otherwise. + example: null + created_at: + type: integer + format: int64 + description: Unix timestamp when the deletion job was created. + example: 1791036405 + started_at: + type: integer + format: int64 + nullable: true + description: >- + Unix timestamp when processing of the deletion job started, or null if + the job is still queued. + example: 1791036410 + completed_at: + type: integer + format: int64 + nullable: true + description: >- + Unix timestamp when the deletion job finished, or null if it is still in + progress. + example: null +required: + - team_id + - deletion_id + - type + - status + - created_at diff --git a/specification/resources/signals/parameters.yml b/specification/resources/signals/parameters.yml index 30fd3db09..963aa9936 100644 --- a/specification/resources/signals/parameters.yml +++ b/specification/resources/signals/parameters.yml @@ -28,6 +28,15 @@ export_id: format: uuid example: 9f13c09c-c877-436b-9863-dcc39c9dd737 +deletion_id: + in: path + name: deletion_id + description: A unique identifier for a data deletion job. + required: true + schema: + type: string + example: 01J9ZX0N5Q7M2K3R4S5T6V7W8X + limit: in: query name: limit diff --git a/specification/resources/signals/responses/deletion_job_accepted_response.yml b/specification/resources/signals/responses/deletion_job_accepted_response.yml new file mode 100644 index 000000000..2c3ad061f --- /dev/null +++ b/specification/resources/signals/responses/deletion_job_accepted_response.yml @@ -0,0 +1,26 @@ +description: >- + The deletion job was accepted. The job is queued and processed + asynchronously. + +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/deletion_job.yml' + example: + team_id: 12345678 + deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X + type: managed_agent + agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 + status: queued + error_message: null + created_at: 1791036405 + started_at: null + completed_at: null diff --git a/specification/resources/signals/responses/deletion_job_response.yml b/specification/resources/signals/responses/deletion_job_response.yml new file mode 100644 index 000000000..081f9954c --- /dev/null +++ b/specification/resources/signals/responses/deletion_job_response.yml @@ -0,0 +1,24 @@ +description: A single deletion 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/deletion_job.yml' + example: + team_id: 12345678 + deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X + type: managed_agent + agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 + status: running + error_message: null + created_at: 1791036405 + started_at: 1791036410 + completed_at: null diff --git a/specification/resources/signals/responses/list_deletions_response.yml b/specification/resources/signals/responses/list_deletions_response.yml new file mode 100644 index 000000000..2844331f0 --- /dev/null +++ b/specification/resources/signals/responses/list_deletions_response.yml @@ -0,0 +1,64 @@ +description: A paginated list of deletion 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: eyJkIjoiMDFKOVpYME41UTdNMksz + node: + $ref: '../models/deletion_job.yml' + page_info: + type: object + properties: + has_next_page: + type: boolean + description: Whether there are more results after this page. + end_cursor: + type: string + description: >- + The cursor of the last item on this page. Pass this value as + `after` to retrieve the next page. Present only when there are + more results. + example: eyJkIjoiMDFKOVpXN0E4QjlDMEQx + example: + edges: + - cursor: eyJkIjoiMDFKOVpYME41UTdNMksz + node: + team_id: 12345678 + deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X + type: managed_agent + agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 + status: complete + error_message: null + created_at: 1791036405 + started_at: 1791036410 + completed_at: 1791036705 + - cursor: eyJkIjoiMDFKOVpXN0E4QjlDMEQx + node: + team_id: 12345678 + deletion_id: 01J9ZW7A8B9C0D1E2F3G4H5J6K + type: inference + status: failed + error_message: max attempts exceeded + created_at: 1790950005 + started_at: 1790950010 + completed_at: 1790950605 + page_info: + has_next_page: false diff --git a/specification/resources/signals/signals_create_deletion.yml b/specification/resources/signals/signals_create_deletion.yml new file mode 100644 index 000000000..6a0cf1c6a --- /dev/null +++ b/specification/resources/signals/signals_create_deletion.yml @@ -0,0 +1,81 @@ +operationId: signals_create_deletion + +summary: Create a Data Deletion Job + +description: | + To permanently delete signals data, send a POST request to + `/v1/signals/deletions`. The request body must include a `type` and the + `team_id` of the authenticated team. + + | Type | Scope | Required Fields | + |------|-------|-----------------| + | `managed_agent` | All signals data (dialogues, events, signal reports, sessions) for one managed agent. Also disables signals collection consent for the agent. | `type`, `team_id`, `agent_id` | + | `inference` | All signals data from the team's inference (non-agent) usage. | `type`, `team_id` | + + **Deletion is permanent and cannot be undone.** Matching data is hidden + immediately and deleted in the background. Poll the get deletion endpoint + to check the job's status. + + The endpoint is idempotent while a job is active. A new job returns + `202 Accepted`. If a queued or running job already exists for the same + target, that job is returned with `200 OK` instead of creating a duplicate. + A request made after the previous job has finished starts a new job. + + Each team may have a limited number of active deletion jobs at once. + Requests beyond that limit return `429 Too Many Requests`; wait for existing + jobs to finish before submitting more. + +tags: + - Signals + +requestBody: + required: true + content: + application/json: + schema: + $ref: 'models/create_deletion_request.yml' + examples: + Managed Agent: + value: + type: managed_agent + team_id: 12345678 + agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 + Inference: + value: + type: inference + team_id: 12345678 + +responses: + '200': + $ref: 'responses/deletion_job_response.yml' + + '202': + $ref: 'responses/deletion_job_accepted_response.yml' + + '400': + $ref: '../../shared/responses/bad_request.yml' + + '401': + $ref: '../../shared/responses/unauthorized.yml' + + '403': + $ref: '../../shared/responses/forbidden.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_create_deletion.yml' + +security: + - bearer_auth: + - 'signals:delete' diff --git a/specification/resources/signals/signals_get_deletion.yml b/specification/resources/signals/signals_get_deletion.yml new file mode 100644 index 000000000..a807ae90f --- /dev/null +++ b/specification/resources/signals/signals_get_deletion.yml @@ -0,0 +1,39 @@ +operationId: signals_get_deletion + +summary: Retrieve a Data Deletion Job + +description: | + To retrieve the status and details of a signals data deletion job, send a + GET request to `/v1/signals/deletions/{deletion_id}`. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/deletion_id' + +responses: + '200': + $ref: 'responses/deletion_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_deletion.yml' + +security: + - bearer_auth: + - 'signals:read' diff --git a/specification/resources/signals/signals_list_deletions.yml b/specification/resources/signals/signals_list_deletions.yml new file mode 100644 index 000000000..3b1b881b9 --- /dev/null +++ b/specification/resources/signals/signals_list_deletions.yml @@ -0,0 +1,43 @@ +operationId: signals_list_deletions + +summary: List Data Deletion Jobs + +description: | + To list signals data deletion jobs for your team, newest first, send a GET + request to `/v1/signals/deletions`. Results are paginated using + cursor-based pagination with `limit` and `after` parameters. To fetch the + next page, pass the `cursor` of the last edge (or `page_info.end_cursor`) + as `after`. + +tags: + - Signals + +parameters: + - $ref: 'parameters.yml#/limit' + - $ref: 'parameters.yml#/after' + +responses: + '200': + $ref: 'responses/list_deletions_response.yml' + + '400': + $ref: '../../shared/responses/bad_request.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_deletions.yml' + +security: + - bearer_auth: + - 'signals:read' From 0809488972ac3b62e010400d0f96173f9ef5db0c Mon Sep 17 00:00:00 2001 From: Satyam Date: Fri, 9 Oct 2026 16:47:59 +0530 Subject: [PATCH 2/4] Align Signals deletion spec with product docs and #1253 conventions - Describe deletion types in terms of agents (Harness Runtime Environment Config ID) and Serverless Inference, matching the existing Signals spec. - List what is deleted as sessions, dialogues, and signal reports, and note that earlier export files are not removed, matching product docs. - Document consent being disabled for managed_agent deletions and that inference deletions only cover data collected before the request. - Drop the internal error text from examples and use well-formed cursors. Co-authored-by: Cursor --- .../models/create_deletion_request.yml | 13 ++++++----- .../resources/signals/models/deletion_job.yml | 22 +++++++++---------- .../responses/list_deletions_response.yml | 16 +++++++------- .../signals/signals_create_deletion.yml | 19 +++++++++++----- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/specification/resources/signals/models/create_deletion_request.yml b/specification/resources/signals/models/create_deletion_request.yml index 4e4f5269c..aee479240 100644 --- a/specification/resources/signals/models/create_deletion_request.yml +++ b/specification/resources/signals/models/create_deletion_request.yml @@ -4,10 +4,10 @@ properties: type: type: string description: >- - The scope of the deletion. `managed_agent` deletes all signals data for - one managed agent and requires `agent_id`. `inference` deletes all - signals data from the team's inference (non-agent) usage and must not - include `agent_id`. + The scope of the deletion. `managed_agent` deletes the signals data + collected for one agent and requires `agent_id`. `inference` deletes the + signals data collected for the team's Serverless Inference requests and + must not include `agent_id`. enum: - managed_agent - inference @@ -21,8 +21,9 @@ properties: type: string format: uuid description: >- - The managed agent whose data should be deleted. Required when `type` is - `managed_agent`; must be omitted when `type` is `inference`. + The agent whose data should be deleted. For Harness Runtime, this is the + Environment Config ID. Required when `type` is `managed_agent`; must be + omitted when `type` is `inference`. example: 01a10d3f-2c09-764f-99f8-458e521627f3 required: - type diff --git a/specification/resources/signals/models/deletion_job.yml b/specification/resources/signals/models/deletion_job.yml index e917a5984..cd3b2a1f6 100644 --- a/specification/resources/signals/models/deletion_job.yml +++ b/specification/resources/signals/models/deletion_job.yml @@ -1,7 +1,7 @@ type: object description: >- - A data deletion job that permanently removes signals data for a managed - agent or for a team's inference usage. + A data deletion job that permanently removes signals data for an agent or + for a team's Serverless Inference usage. properties: team_id: type: integer @@ -15,9 +15,9 @@ properties: type: type: string description: >- - The scope of the deletion. `managed_agent` deletes all signals data for - one managed agent. `inference` deletes all signals data from the team's - inference (non-agent) usage. + The scope of the deletion. `managed_agent` deletes the signals data + collected for one agent. `inference` deletes the signals data collected + for the team's Serverless Inference requests. enum: - managed_agent - inference @@ -26,16 +26,16 @@ properties: type: string format: uuid description: >- - The managed agent whose data is being deleted. Only present for - `managed_agent` deletions. + The agent whose data is being deleted. For Harness Runtime, this is the + Environment Config ID. Only present for `managed_agent` deletions. example: 01a10d3f-2c09-764f-99f8-458e521627f3 status: type: string description: >- The current status of the deletion job. `queued` jobs are waiting to be - processed, `running` jobs are actively deleting data, `complete` jobs - have permanently deleted all matching data, and `failed` jobs stopped - with an error described in `error_message`. + processed, `running` jobs are deleting data, `complete` jobs have + permanently deleted all matching data, and `failed` jobs stopped before + finishing. enum: - queued - running @@ -45,7 +45,7 @@ properties: error_message: type: string nullable: true - description: Error message if the deletion failed, or null otherwise. + description: A description of why the deletion failed, or null if it has not failed. example: null created_at: type: integer diff --git a/specification/resources/signals/responses/list_deletions_response.yml b/specification/resources/signals/responses/list_deletions_response.yml index 2844331f0..626c4668d 100644 --- a/specification/resources/signals/responses/list_deletions_response.yml +++ b/specification/resources/signals/responses/list_deletions_response.yml @@ -21,7 +21,7 @@ content: cursor: type: string description: An opaque cursor for pagination. - example: eyJkIjoiMDFKOVpYME41UTdNMksz + example: eyJkIjoiMDFKOVpYME41UTdNMkszUjRTNVQ2VjdXOFgifQ== node: $ref: '../models/deletion_job.yml' page_info: @@ -36,27 +36,27 @@ content: The cursor of the last item on this page. Pass this value as `after` to retrieve the next page. Present only when there are more results. - example: eyJkIjoiMDFKOVpXN0E4QjlDMEQx + example: eyJkIjoiMDFKOVpXN0E4QjlDMEQxRTJGM0c0SDVKNksifQ== example: edges: - - cursor: eyJkIjoiMDFKOVpYME41UTdNMksz + - cursor: eyJkIjoiMDFKOVpYME41UTdNMkszUjRTNVQ2VjdXOFgifQ== node: team_id: 12345678 deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X type: managed_agent agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 - status: complete + status: running error_message: null created_at: 1791036405 started_at: 1791036410 - completed_at: 1791036705 - - cursor: eyJkIjoiMDFKOVpXN0E4QjlDMEQx + completed_at: null + - cursor: eyJkIjoiMDFKOVpXN0E4QjlDMEQxRTJGM0c0SDVKNksifQ== node: team_id: 12345678 deletion_id: 01J9ZW7A8B9C0D1E2F3G4H5J6K type: inference - status: failed - error_message: max attempts exceeded + status: complete + error_message: null created_at: 1790950005 started_at: 1790950010 completed_at: 1790950605 diff --git a/specification/resources/signals/signals_create_deletion.yml b/specification/resources/signals/signals_create_deletion.yml index 6a0cf1c6a..2d2f3d1b0 100644 --- a/specification/resources/signals/signals_create_deletion.yml +++ b/specification/resources/signals/signals_create_deletion.yml @@ -9,12 +9,21 @@ description: | | Type | Scope | Required Fields | |------|-------|-----------------| - | `managed_agent` | All signals data (dialogues, events, signal reports, sessions) for one managed agent. Also disables signals collection consent for the agent. | `type`, `team_id`, `agent_id` | - | `inference` | All signals data from the team's inference (non-agent) usage. | `type`, `team_id` | + | `managed_agent` | The sessions, dialogues, and signal reports collected for one agent. | `type`, `team_id`, `agent_id` | + | `inference` | The sessions, dialogues, and signal reports collected for the team's Serverless Inference requests. | `type`, `team_id` | - **Deletion is permanent and cannot be undone.** Matching data is hidden - immediately and deleted in the background. Poll the get deletion endpoint - to check the job's status. + **Deletion is permanent and cannot be undone.** Deletion runs in the + background. Poll the get deletion endpoint to check the job's status. + + For `managed_agent` deletions, the agent's sessions and dialogues stop + appearing in signals results immediately, and signals collection is + disabled for the agent. Wait until the deletion is complete before enabling + signals for the agent again. For `inference` deletions, only data collected + before the request is deleted; signals continues to analyze new Serverless + Inference requests. + + Deletion does not remove export files created earlier. They remain + available to download until they expire. The endpoint is idempotent while a job is active. A new job returns `202 Accepted`. If a queued or running job already exists for the same From 8ec2b3b23bb17958a0da33524c4b5ece6a76eed0 Mon Sep 17 00:00:00 2001 From: Satyam Date: Fri, 9 Oct 2026 17:47:44 +0530 Subject: [PATCH 3/4] Rename Signals deletion type managed_agent to agent signals-api now accepts and returns type "agent" (cthulhu#180125), and doctl#2021 and godo#1152 use the same name. Also document that a failed agent deletion keeps the data hidden and collection disabled, and that retrying means submitting the request again, matching product docs. Co-authored-by: Cursor --- .../examples/curl/signals_create_deletion.yml | 2 +- .../models/create_deletion_request.yml | 8 +++---- .../resources/signals/models/deletion_job.yml | 8 +++---- .../deletion_job_accepted_response.yml | 2 +- .../responses/deletion_job_response.yml | 2 +- .../responses/list_deletions_response.yml | 2 +- .../signals/signals_create_deletion.yml | 22 ++++++++++--------- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/specification/resources/signals/examples/curl/signals_create_deletion.yml b/specification/resources/signals/examples/curl/signals_create_deletion.yml index 522f3617b..1b847dd1f 100644 --- a/specification/resources/signals/examples/curl/signals_create_deletion.yml +++ b/specification/resources/signals/examples/curl/signals_create_deletion.yml @@ -3,5 +3,5 @@ source: |- curl -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ - -d '{"type":"managed_agent","team_id":12345678,"agent_id":"01a10d3f-2c09-764f-99f8-458e521627f3"}' \ + -d '{"type":"agent","team_id":12345678,"agent_id":"01a10d3f-2c09-764f-99f8-458e521627f3"}' \ "https://api.digitalocean.com/v1/signals/deletions" diff --git a/specification/resources/signals/models/create_deletion_request.yml b/specification/resources/signals/models/create_deletion_request.yml index aee479240..baed0d068 100644 --- a/specification/resources/signals/models/create_deletion_request.yml +++ b/specification/resources/signals/models/create_deletion_request.yml @@ -4,14 +4,14 @@ properties: type: type: string description: >- - The scope of the deletion. `managed_agent` deletes the signals data + The scope of the deletion. `agent` deletes the signals data collected for one agent and requires `agent_id`. `inference` deletes the signals data collected for the team's Serverless Inference requests and must not include `agent_id`. enum: - - managed_agent + - agent - inference - example: managed_agent + example: agent team_id: type: integer format: int64 @@ -22,7 +22,7 @@ properties: format: uuid description: >- The agent whose data should be deleted. For Harness Runtime, this is the - Environment Config ID. Required when `type` is `managed_agent`; must be + Environment Config ID. Required when `type` is `agent`; must be omitted when `type` is `inference`. example: 01a10d3f-2c09-764f-99f8-458e521627f3 required: diff --git a/specification/resources/signals/models/deletion_job.yml b/specification/resources/signals/models/deletion_job.yml index cd3b2a1f6..cc6d86941 100644 --- a/specification/resources/signals/models/deletion_job.yml +++ b/specification/resources/signals/models/deletion_job.yml @@ -15,19 +15,19 @@ properties: type: type: string description: >- - The scope of the deletion. `managed_agent` deletes the signals data + The scope of the deletion. `agent` deletes the signals data collected for one agent. `inference` deletes the signals data collected for the team's Serverless Inference requests. enum: - - managed_agent + - agent - inference - example: managed_agent + example: agent agent_id: type: string format: uuid description: >- The agent whose data is being deleted. For Harness Runtime, this is the - Environment Config ID. Only present for `managed_agent` deletions. + Environment Config ID. Only present for `agent` deletions. example: 01a10d3f-2c09-764f-99f8-458e521627f3 status: type: string diff --git a/specification/resources/signals/responses/deletion_job_accepted_response.yml b/specification/resources/signals/responses/deletion_job_accepted_response.yml index 2c3ad061f..bab88b1c7 100644 --- a/specification/resources/signals/responses/deletion_job_accepted_response.yml +++ b/specification/resources/signals/responses/deletion_job_accepted_response.yml @@ -17,7 +17,7 @@ content: example: team_id: 12345678 deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X - type: managed_agent + type: agent agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 status: queued error_message: null diff --git a/specification/resources/signals/responses/deletion_job_response.yml b/specification/resources/signals/responses/deletion_job_response.yml index 081f9954c..405438ecd 100644 --- a/specification/resources/signals/responses/deletion_job_response.yml +++ b/specification/resources/signals/responses/deletion_job_response.yml @@ -15,7 +15,7 @@ content: example: team_id: 12345678 deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X - type: managed_agent + type: agent agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 status: running error_message: null diff --git a/specification/resources/signals/responses/list_deletions_response.yml b/specification/resources/signals/responses/list_deletions_response.yml index 626c4668d..e8a5a0ee6 100644 --- a/specification/resources/signals/responses/list_deletions_response.yml +++ b/specification/resources/signals/responses/list_deletions_response.yml @@ -43,7 +43,7 @@ content: node: team_id: 12345678 deletion_id: 01J9ZX0N5Q7M2K3R4S5T6V7W8X - type: managed_agent + type: agent agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 status: running error_message: null diff --git a/specification/resources/signals/signals_create_deletion.yml b/specification/resources/signals/signals_create_deletion.yml index 2d2f3d1b0..b929395d6 100644 --- a/specification/resources/signals/signals_create_deletion.yml +++ b/specification/resources/signals/signals_create_deletion.yml @@ -9,18 +9,20 @@ description: | | Type | Scope | Required Fields | |------|-------|-----------------| - | `managed_agent` | The sessions, dialogues, and signal reports collected for one agent. | `type`, `team_id`, `agent_id` | + | `agent` | The sessions, dialogues, and signal reports collected for one agent. | `type`, `team_id`, `agent_id` | | `inference` | The sessions, dialogues, and signal reports collected for the team's Serverless Inference requests. | `type`, `team_id` | **Deletion is permanent and cannot be undone.** Deletion runs in the - background. Poll the get deletion endpoint to check the job's status. + background. Poll the get deletion endpoint to check the job's status. If a + job fails, submit the same request again to retry. - For `managed_agent` deletions, the agent's sessions and dialogues stop - appearing in signals results immediately, and signals collection is - disabled for the agent. Wait until the deletion is complete before enabling - signals for the agent again. For `inference` deletions, only data collected - before the request is deleted; signals continues to analyze new Serverless - Inference requests. + For `agent` deletions, the agent's sessions and dialogues stop appearing in + signals results immediately, and signals collection is disabled for the + agent. They stay hidden and collection stays disabled even if the job + fails. Wait until the deletion is complete before enabling signals for the + agent again. For `inference` deletions, only data collected before the + request is deleted; signals continues to analyze new Serverless Inference + requests. Deletion does not remove export files created earlier. They remain available to download until they expire. @@ -44,9 +46,9 @@ requestBody: schema: $ref: 'models/create_deletion_request.yml' examples: - Managed Agent: + Agent: value: - type: managed_agent + type: agent team_id: 12345678 agent_id: 01a10d3f-2c09-764f-99f8-458e521627f3 Inference: From 2ebdc566dbca6c694086fe6359428944a6c2f353 Mon Sep 17 00:00:00 2001 From: Satyam Date: Fri, 9 Oct 2026 18:01:08 +0530 Subject: [PATCH 4/4] Simplify Signals deletion descriptions Adopt the shorter, table-free style from satyambhalla/openapi#1 to match the export endpoints, and note that deletion_id is a ULID. Keep the facts that product docs also state: the Harness Runtime Environment Config ID note on agent_id, waiting for an agent deletion to finish before re-enabling signals, data staying hidden after a failed job and retrying by resending, inference deletions covering only earlier requests, export files not being deleted, the 429 active-job limit, and newest-first list ordering. Co-authored-by: aupadhyay-shark Co-authored-by: Cursor --- .../models/create_deletion_request.yml | 13 +++-- .../resources/signals/models/deletion_job.yml | 27 +++------- .../deletion_job_accepted_response.yml | 3 +- .../responses/list_deletions_response.yml | 5 +- .../signals/signals_create_deletion.yml | 52 ++++++++----------- .../signals/signals_get_deletion.yml | 4 +- .../signals/signals_list_deletions.yml | 4 +- 7 files changed, 41 insertions(+), 67 deletions(-) diff --git a/specification/resources/signals/models/create_deletion_request.yml b/specification/resources/signals/models/create_deletion_request.yml index baed0d068..eea28cfb5 100644 --- a/specification/resources/signals/models/create_deletion_request.yml +++ b/specification/resources/signals/models/create_deletion_request.yml @@ -4,10 +4,9 @@ properties: type: type: string description: >- - The scope of the deletion. `agent` deletes the signals data - collected for one agent and requires `agent_id`. `inference` deletes the - signals data collected for the team's Serverless Inference requests and - must not include `agent_id`. + The scope of the deletion. `agent` deletes data for one agent and + requires `agent_id`. `inference` deletes data for the team's Serverless + Inference requests. enum: - agent - inference @@ -15,15 +14,15 @@ properties: team_id: type: integer format: int64 - description: The team whose data should be deleted. Must match the team of the authenticated token. + description: The team whose data should be deleted. Must match the authenticated team. example: 12345678 agent_id: type: string format: uuid description: >- The agent whose data should be deleted. For Harness Runtime, this is the - Environment Config ID. Required when `type` is `agent`; must be - omitted when `type` is `inference`. + Environment Config ID. Required when `type` is `agent`; must be omitted + when `type` is `inference`. example: 01a10d3f-2c09-764f-99f8-458e521627f3 required: - type diff --git a/specification/resources/signals/models/deletion_job.yml b/specification/resources/signals/models/deletion_job.yml index cc6d86941..e2375ade5 100644 --- a/specification/resources/signals/models/deletion_job.yml +++ b/specification/resources/signals/models/deletion_job.yml @@ -1,7 +1,5 @@ type: object -description: >- - A data deletion job that permanently removes signals data for an agent or - for a team's Serverless Inference usage. +description: A deletion job that permanently removes signals data for an agent or for a team's Serverless Inference usage. properties: team_id: type: integer @@ -10,14 +8,13 @@ properties: example: 12345678 deletion_id: type: string - description: The unique identifier for the deletion job. + description: The unique identifier for the deletion job (ULID). example: 01J9ZX0N5Q7M2K3R4S5T6V7W8X type: type: string description: >- - The scope of the deletion. `agent` deletes the signals data - collected for one agent. `inference` deletes the signals data collected - for the team's Serverless Inference requests. + The scope of the deletion. `agent` deletes data for one agent. + `inference` deletes data for the team's Serverless Inference requests. enum: - agent - inference @@ -31,11 +28,7 @@ properties: example: 01a10d3f-2c09-764f-99f8-458e521627f3 status: type: string - description: >- - The current status of the deletion job. `queued` jobs are waiting to be - processed, `running` jobs are deleting data, `complete` jobs have - permanently deleted all matching data, and `failed` jobs stopped before - finishing. + description: The current status of the deletion job. enum: - queued - running @@ -45,7 +38,7 @@ properties: error_message: type: string nullable: true - description: A description of why the deletion failed, or null if it has not failed. + description: Error message if the deletion failed, or null otherwise. example: null created_at: type: integer @@ -56,17 +49,13 @@ properties: type: integer format: int64 nullable: true - description: >- - Unix timestamp when processing of the deletion job started, or null if - the job is still queued. + description: Unix timestamp when processing started, or null if still queued. example: 1791036410 completed_at: type: integer format: int64 nullable: true - description: >- - Unix timestamp when the deletion job finished, or null if it is still in - progress. + description: Unix timestamp when the deletion finished, or null if still in progress. example: null required: - team_id diff --git a/specification/resources/signals/responses/deletion_job_accepted_response.yml b/specification/resources/signals/responses/deletion_job_accepted_response.yml index bab88b1c7..32ab717df 100644 --- a/specification/resources/signals/responses/deletion_job_accepted_response.yml +++ b/specification/resources/signals/responses/deletion_job_accepted_response.yml @@ -1,6 +1,5 @@ description: >- - The deletion job was accepted. The job is queued and processed - asynchronously. + The deletion job was accepted and will be processed asynchronously. headers: ratelimit-limit: diff --git a/specification/resources/signals/responses/list_deletions_response.yml b/specification/resources/signals/responses/list_deletions_response.yml index e8a5a0ee6..8b5a8c888 100644 --- a/specification/resources/signals/responses/list_deletions_response.yml +++ b/specification/resources/signals/responses/list_deletions_response.yml @@ -33,9 +33,8 @@ content: end_cursor: type: string description: >- - The cursor of the last item on this page. Pass this value as - `after` to retrieve the next page. Present only when there are - more results. + Cursor of the last item. Pass as `after` to fetch the next + page. Present only when there are more results. example: eyJkIjoiMDFKOVpXN0E4QjlDMEQxRTJGM0c0SDVKNksifQ== example: edges: diff --git a/specification/resources/signals/signals_create_deletion.yml b/specification/resources/signals/signals_create_deletion.yml index b929395d6..d7365e5f7 100644 --- a/specification/resources/signals/signals_create_deletion.yml +++ b/specification/resources/signals/signals_create_deletion.yml @@ -4,37 +4,27 @@ summary: Create a Data Deletion Job description: | To permanently delete signals data, send a POST request to - `/v1/signals/deletions`. The request body must include a `type` and the - `team_id` of the authenticated team. - - | Type | Scope | Required Fields | - |------|-------|-----------------| - | `agent` | The sessions, dialogues, and signal reports collected for one agent. | `type`, `team_id`, `agent_id` | - | `inference` | The sessions, dialogues, and signal reports collected for the team's Serverless Inference requests. | `type`, `team_id` | - - **Deletion is permanent and cannot be undone.** Deletion runs in the - background. Poll the get deletion endpoint to check the job's status. If a - job fails, submit the same request again to retry. - - For `agent` deletions, the agent's sessions and dialogues stop appearing in - signals results immediately, and signals collection is disabled for the - agent. They stay hidden and collection stays disabled even if the job - fails. Wait until the deletion is complete before enabling signals for the - agent again. For `inference` deletions, only data collected before the - request is deleted; signals continues to analyze new Serverless Inference - requests. - - Deletion does not remove export files created earlier. They remain - available to download until they expire. - - The endpoint is idempotent while a job is active. A new job returns - `202 Accepted`. If a queued or running job already exists for the same - target, that job is returned with `200 OK` instead of creating a duplicate. - A request made after the previous job has finished starts a new job. - - Each team may have a limited number of active deletion jobs at once. - Requests beyond that limit return `429 Too Many Requests`; wait for existing - jobs to finish before submitting more. + `/v1/signals/deletions`. + + Two deletion types are supported: + + - `agent` — deletes sessions, dialogues, and signal reports for one agent. + Requires `agent_id`. The agent's data is hidden immediately and signals + collection is disabled for the agent, even if the job later fails. Wait + until the job is complete before enabling signals for the agent again. + - `inference` — deletes sessions, dialogues, and signal reports for the + team's Serverless Inference requests made before the deletion. Signals + continues to analyze new requests. + + Deletion is permanent and cannot be undone. The job runs asynchronously; + poll the get endpoint to check status. To retry a failed job, send the same + request again. Export files created earlier are not deleted and remain + available until they expire. + + The endpoint is idempotent: if a queued or running job already exists for + the same target, it is returned with `200 OK`. A new job returns + `202 Accepted`. Each team can have a limited number of active jobs; + requests beyond that limit return `429 Too Many Requests`. tags: - Signals diff --git a/specification/resources/signals/signals_get_deletion.yml b/specification/resources/signals/signals_get_deletion.yml index a807ae90f..756cd6863 100644 --- a/specification/resources/signals/signals_get_deletion.yml +++ b/specification/resources/signals/signals_get_deletion.yml @@ -3,8 +3,8 @@ operationId: signals_get_deletion summary: Retrieve a Data Deletion Job description: | - To retrieve the status and details of a signals data deletion job, send a - GET request to `/v1/signals/deletions/{deletion_id}`. + To retrieve the status of a signals data deletion job, send a GET request + to `/v1/signals/deletions/{deletion_id}`. tags: - Signals diff --git a/specification/resources/signals/signals_list_deletions.yml b/specification/resources/signals/signals_list_deletions.yml index 3b1b881b9..e3bba5ce1 100644 --- a/specification/resources/signals/signals_list_deletions.yml +++ b/specification/resources/signals/signals_list_deletions.yml @@ -5,9 +5,7 @@ summary: List Data Deletion Jobs description: | To list signals data deletion jobs for your team, newest first, send a GET request to `/v1/signals/deletions`. Results are paginated using - cursor-based pagination with `limit` and `after` parameters. To fetch the - next page, pass the `cursor` of the last edge (or `page_info.end_cursor`) - as `after`. + cursor-based pagination with `limit` and `after` parameters. tags: - Signals