From 6281e226b137bb0202229fedd2dd6d444cfbb18c Mon Sep 17 00:00:00 2001 From: Sakshi Rajput Date: Thu, 8 Oct 2026 19:43:05 +0530 Subject: [PATCH 1/4] COBS-1348: Document Insights traces query endpoints Add the public traces search and get-by-id operations so they can appear on the official API docs, matching the existing logs search pattern. --- specification/DigitalOcean-public.v2.yaml | 8 ++ .../examples/curl/insights_get_trace.yml | 5 ++ .../curl/insights_post_tracesSearch.yml | 23 ++++++ .../resources/insights/insights_get_trace.yml | 49 +++++++++++++ .../insights/insights_post_tracesSearch.yml | 57 +++++++++++++++ .../insights/models/traces_field_ref.yml | 23 ++++++ .../models/traces_filter_condition.yml | 21 ++++++ .../models/traces_filter_expression.yml | 37 ++++++++++ .../insights/models/traces_filter_value.yml | 40 ++++++++++ .../insights/models/traces_order_by.yml | 14 ++++ .../models/traces_pagination_request.yml | 11 +++ .../models/traces_pagination_response.yml | 7 ++ .../insights/models/traces_search_request.yml | 16 ++++ .../models/traces_search_response.yml | 10 +++ .../insights/models/traces_span_record.yml | 73 +++++++++++++++++++ .../insights/models/traces_time_instant.yml | 24 ++++++ .../insights/models/traces_time_range.yml | 10 +++ .../insights/models/traces_trace_response.yml | 12 +++ .../insights/models/traces_trace_summary.yml | 49 +++++++++++++ .../resources/insights/parameters.yml | 9 +++ .../resources/insights/responses/trace.yml | 14 ++++ .../insights/responses/traces_search.yml | 14 ++++ 22 files changed, 526 insertions(+) create mode 100644 specification/resources/insights/examples/curl/insights_get_trace.yml create mode 100644 specification/resources/insights/examples/curl/insights_post_tracesSearch.yml create mode 100644 specification/resources/insights/insights_get_trace.yml create mode 100644 specification/resources/insights/insights_post_tracesSearch.yml create mode 100644 specification/resources/insights/models/traces_field_ref.yml create mode 100644 specification/resources/insights/models/traces_filter_condition.yml create mode 100644 specification/resources/insights/models/traces_filter_expression.yml create mode 100644 specification/resources/insights/models/traces_filter_value.yml create mode 100644 specification/resources/insights/models/traces_order_by.yml create mode 100644 specification/resources/insights/models/traces_pagination_request.yml create mode 100644 specification/resources/insights/models/traces_pagination_response.yml create mode 100644 specification/resources/insights/models/traces_search_request.yml create mode 100644 specification/resources/insights/models/traces_search_response.yml create mode 100644 specification/resources/insights/models/traces_span_record.yml create mode 100644 specification/resources/insights/models/traces_time_instant.yml create mode 100644 specification/resources/insights/models/traces_time_range.yml create mode 100644 specification/resources/insights/models/traces_trace_response.yml create mode 100644 specification/resources/insights/models/traces_trace_summary.yml create mode 100644 specification/resources/insights/responses/trace.yml create mode 100644 specification/resources/insights/responses/traces_search.yml diff --git a/specification/DigitalOcean-public.v2.yaml b/specification/DigitalOcean-public.v2.yaml index a26d71aa6..4366f2468 100644 --- a/specification/DigitalOcean-public.v2.yaml +++ b/specification/DigitalOcean-public.v2.yaml @@ -1827,6 +1827,14 @@ paths: post: $ref: "resources/insights/insights_post_logsSearch.yml" + /v2/insights/query/{region}/traces/search: + post: + $ref: "resources/insights/insights_post_tracesSearch.yml" + + /v2/insights/query/{region}/traces/{trace_id}: + get: + $ref: "resources/insights/insights_get_trace.yml" + /v2/kubernetes/clusters: get: $ref: "resources/kubernetes/kubernetes_list_clusters.yml" diff --git a/specification/resources/insights/examples/curl/insights_get_trace.yml b/specification/resources/insights/examples/curl/insights_get_trace.yml new file mode 100644 index 000000000..d34b16321 --- /dev/null +++ b/specification/resources/insights/examples/curl/insights_get_trace.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl -X GET \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v2/insights/query/nyc3/traces/4bf92f3577b34da6a3ce929d0e0e4736" diff --git a/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml b/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml new file mode 100644 index 000000000..b5c144ff5 --- /dev/null +++ b/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml @@ -0,0 +1,23 @@ +lang: cURL +source: |- + curl -X POST \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "time_range": { + "from": {"absolute": "2026-09-30T00:00:00Z"}, + "to": {"absolute": "2026-09-30T01:00:00Z"} + }, + "filter": { + "condition": { + "field": {"name": "service.name"}, + "operator": "FILTER_OPERATOR_EQ", + "value": {"string_value": "api-gateway"} + } + }, + "order_by": [ + {"field": {"name": "started"}, "direction": "SORT_DIRECTION_DESC"} + ], + "pagination": {"limit": 100} + }' \ + "https://api.digitalocean.com/v2/insights/query/nyc3/traces/search" diff --git a/specification/resources/insights/insights_get_trace.yml b/specification/resources/insights/insights_get_trace.yml new file mode 100644 index 000000000..416273a8c --- /dev/null +++ b/specification/resources/insights/insights_get_trace.yml @@ -0,0 +1,49 @@ +operationId: insights_get_trace + +summary: Retrieve an existing trace + +description: >- + To retrieve a single trace and all of its spans, send a GET request to + `/v2/insights/query/{region}/traces/{trace_id}`. + + Spans are returned ordered by start time. A trace is only resolvable in the + region that ingested it; querying another region returns `404`. + +tags: + - Insights + +parameters: + - $ref: 'parameters.yml#/region' + - $ref: 'parameters.yml#/trace_id' + +responses: + '200': + $ref: 'responses/trace.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/insights_get_trace.yml' + +security: + - bearer_auth: + - 'insights:read' diff --git a/specification/resources/insights/insights_post_tracesSearch.yml b/specification/resources/insights/insights_post_tracesSearch.yml new file mode 100644 index 000000000..11d444072 --- /dev/null +++ b/specification/resources/insights/insights_post_tracesSearch.yml @@ -0,0 +1,57 @@ +operationId: insights_post_tracesSearch + +summary: Search traces + +description: >- + To search traces in a region, send a POST request to + `/v2/insights/query/{region}/traces/search` with a JSON body describing the + time range, optional filter, ordering, and pagination. + + Each result is one trace, aggregated from its spans. The time range must not + exceed 7 days. `pagination.limit` defaults to 100 and is clamped to 1000. + Results are ordered by `started` descending unless `order_by` is set. + +tags: + - Insights + +parameters: + - $ref: 'parameters.yml#/region' + +requestBody: + required: true + content: + application/json: + schema: + $ref: 'models/traces_search_request.yml' + +responses: + '200': + $ref: 'responses/traces_search.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/insights_post_tracesSearch.yml' + +security: + - bearer_auth: + - 'insights:read' diff --git a/specification/resources/insights/models/traces_field_ref.yml b/specification/resources/insights/models/traces_field_ref.yml new file mode 100644 index 000000000..226d49a2f --- /dev/null +++ b/specification/resources/insights/models/traces_field_ref.yml @@ -0,0 +1,23 @@ +type: object +description: A reference to a logical field for filters or ordering. +required: + - name +properties: + name: + type: string + description: >- + The field name. Intrinsic span columns include `trace_id`, `span_id`, + `parent_span_id`, `start_time`, `end_time`, `duration_ns`, `name`, + `kind`, `status_code`, and `status_message`. Trace-level columns include + `started`, `duration_ns`, `span_count`, `error_count`, and `status`. The + dotted shorthands `service.name`, `resource.type`, and `resource.urn` are + also supported. Arbitrary resource or span attributes can be accessed + with `ResourceAttributes['key']` or `SpanAttributes['key']`. + example: service.name + scope: + type: string + description: The attribute scope to resolve the field against. Omit to let the server apply its default mapping for the field name. + enum: + - FIELD_SCOPE_RESOURCE + - FIELD_SCOPE_ATTRIBUTES + example: FIELD_SCOPE_RESOURCE diff --git a/specification/resources/insights/models/traces_filter_condition.yml b/specification/resources/insights/models/traces_filter_condition.yml new file mode 100644 index 000000000..6d0cae25f --- /dev/null +++ b/specification/resources/insights/models/traces_filter_condition.yml @@ -0,0 +1,21 @@ +type: object +description: A single field comparison in a traces filter expression. +required: + - field + - operator +properties: + field: + $ref: 'traces_field_ref.yml' + operator: + type: string + description: The comparison operator. + enum: + - FILTER_OPERATOR_EQ + - FILTER_OPERATOR_NEQ + - FILTER_OPERATOR_IN + - FILTER_OPERATOR_EXISTS + - FILTER_OPERATOR_GTE + - FILTER_OPERATOR_LTE + example: FILTER_OPERATOR_EQ + value: + $ref: 'traces_filter_value.yml' diff --git a/specification/resources/insights/models/traces_filter_expression.yml b/specification/resources/insights/models/traces_filter_expression.yml new file mode 100644 index 000000000..65b4e5507 --- /dev/null +++ b/specification/resources/insights/models/traces_filter_expression.yml @@ -0,0 +1,37 @@ +type: object +description: A boolean filter tree for traces queries. Exactly one node is set per message. +minProperties: 1 +maxProperties: 1 +properties: + condition: + $ref: 'traces_filter_condition.yml' + and: + type: object + required: + - expressions + properties: + expressions: + type: array + items: + $ref: 'traces_filter_expression.yml' + or: + type: object + required: + - expressions + properties: + expressions: + type: array + items: + $ref: 'traces_filter_expression.yml' + not: + $ref: 'traces_filter_expression.yml' + text_search: + type: object + description: A substring search across the span name, service name, and resource URN. + required: + - query + properties: + query: + type: string + description: The search string. + example: "checkout" diff --git a/specification/resources/insights/models/traces_filter_value.yml b/specification/resources/insights/models/traces_filter_value.yml new file mode 100644 index 000000000..d917c99c2 --- /dev/null +++ b/specification/resources/insights/models/traces_filter_value.yml @@ -0,0 +1,40 @@ +type: object +description: A typed literal or list value for a filter condition. Exactly one kind is set per message. +minProperties: 1 +maxProperties: 1 +properties: + string_value: + type: string + example: "api-gateway" + number_value: + type: number + example: 42 + bool_value: + type: boolean + example: true + string_array_value: + type: object + required: + - values + properties: + values: + type: array + minItems: 1 + items: + type: string + example: + - "api-gateway" + - "auth-service" + number_array_value: + type: object + required: + - values + properties: + values: + type: array + minItems: 1 + items: + type: number + example: + - 42 + - 84 diff --git a/specification/resources/insights/models/traces_order_by.yml b/specification/resources/insights/models/traces_order_by.yml new file mode 100644 index 000000000..86ae2ff87 --- /dev/null +++ b/specification/resources/insights/models/traces_order_by.yml @@ -0,0 +1,14 @@ +type: object +description: A sort clause for traces search results. +required: + - field +properties: + field: + $ref: 'traces_field_ref.yml' + direction: + type: string + description: The sort direction. Omit to use the server default. + enum: + - SORT_DIRECTION_ASC + - SORT_DIRECTION_DESC + example: SORT_DIRECTION_DESC diff --git a/specification/resources/insights/models/traces_pagination_request.yml b/specification/resources/insights/models/traces_pagination_request.yml new file mode 100644 index 000000000..d7f2790dc --- /dev/null +++ b/specification/resources/insights/models/traces_pagination_request.yml @@ -0,0 +1,11 @@ +type: object +description: Limits the size of a traces search result set. +properties: + limit: + type: integer + format: int32 + description: Maximum number of results to return. Defaults to 100 and is clamped to 1000. + default: 100 + minimum: 1 + maximum: 1000 + example: 100 diff --git a/specification/resources/insights/models/traces_pagination_response.yml b/specification/resources/insights/models/traces_pagination_response.yml new file mode 100644 index 000000000..33c33debf --- /dev/null +++ b/specification/resources/insights/models/traces_pagination_response.yml @@ -0,0 +1,7 @@ +type: object +description: Pagination response. +properties: + has_more: + type: boolean + description: Whether more results matched the query than were returned. + example: true diff --git a/specification/resources/insights/models/traces_search_request.yml b/specification/resources/insights/models/traces_search_request.yml new file mode 100644 index 000000000..11418d5df --- /dev/null +++ b/specification/resources/insights/models/traces_search_request.yml @@ -0,0 +1,16 @@ +type: object +description: Request body for searching traces. +required: + - time_range +properties: + time_range: + $ref: 'traces_time_range.yml' + filter: + $ref: 'traces_filter_expression.yml' + order_by: + type: array + description: Sort clauses applied to the result set. Defaults to `started` descending. + items: + $ref: 'traces_order_by.yml' + pagination: + $ref: 'traces_pagination_request.yml' diff --git a/specification/resources/insights/models/traces_search_response.yml b/specification/resources/insights/models/traces_search_response.yml new file mode 100644 index 000000000..eb730e674 --- /dev/null +++ b/specification/resources/insights/models/traces_search_response.yml @@ -0,0 +1,10 @@ +type: object +description: Response body for a traces search. +properties: + data: + type: array + description: Matching traces. Omitted when no traces match. + items: + $ref: 'traces_trace_summary.yml' + pagination: + $ref: 'traces_pagination_response.yml' diff --git a/specification/resources/insights/models/traces_span_record.yml b/specification/resources/insights/models/traces_span_record.yml new file mode 100644 index 000000000..eb9b351a4 --- /dev/null +++ b/specification/resources/insights/models/traces_span_record.yml @@ -0,0 +1,73 @@ +type: object +description: A single span belonging to a trace. +required: + - trace_id + - span_id +properties: + trace_id: + type: string + description: The trace this span belongs to. + example: "4bf92f3577b34da6a3ce929d0e0e4736" + span_id: + type: string + description: The span identifier. + example: "00f067aa0ba902b7" + parent_span_id: + type: string + description: The parent span identifier. Omitted for the root span. + example: "a2fb4a1d1a96d312" + start_time: + type: string + format: date-time + description: The span start time. + example: "2026-09-30T00:14:12Z" + end_time: + type: string + format: date-time + description: The span end time. + example: "2026-09-30T00:14:12.154Z" + duration_ns: + type: string + format: int64 + description: Span duration in nanoseconds, encoded as a string to preserve 64-bit precision. + example: "154000000" + name: + type: string + description: The span name, typically the operation being performed. + example: "GET /v2/droplets" + kind: + type: string + description: The OpenTelemetry span kind. + example: "SPAN_KIND_SERVER" + status_code: + type: string + description: The OpenTelemetry span status code. + example: "STATUS_CODE_ERROR" + status_message: + type: string + description: The status description. Omitted when empty. + example: "upstream timeout" + service_name: + type: string + description: The service that emitted the span. + example: "api-gateway" + resource: + type: object + description: Resource attributes associated with the span. + additionalProperties: + type: string + example: + do.component: "droplet" + do.droplet.id: "12345678" + attributes: + type: object + description: Span attributes. + additionalProperties: + type: string + example: + http.method: "GET" + http.status_code: "504" + region: + type: string + description: The datacenter region the span was returned from. + example: nyc3 diff --git a/specification/resources/insights/models/traces_time_instant.yml b/specification/resources/insights/models/traces_time_instant.yml new file mode 100644 index 000000000..15401b54d --- /dev/null +++ b/specification/resources/insights/models/traces_time_instant.yml @@ -0,0 +1,24 @@ +type: object +description: A single point in time. Exactly one value form is set per message. +minProperties: 1 +maxProperties: 1 +properties: + absolute: + type: string + format: date-time + description: >- + An absolute timestamp. Accepts RFC3339/RFC3339Nano strings or Unix + seconds/nanoseconds as decimal strings. + example: "2026-09-01T00:00:00Z" + relative: + type: string + description: >- + A relative time. Use `now` for the current time, a bare duration such as + `1h` or `7d` to look back from now, or an offset such as `now-1h` or + `now+30m`. Supported units are `s`, `m`, `h`, `d`, and `w`. + example: "1h" + unix_nano: + type: string + format: int64 + description: A Unix nanosecond timestamp, encoded as a string to preserve 64-bit precision. + example: "1756684800000000000" diff --git a/specification/resources/insights/models/traces_time_range.yml b/specification/resources/insights/models/traces_time_range.yml new file mode 100644 index 000000000..9828f3b2e --- /dev/null +++ b/specification/resources/insights/models/traces_time_range.yml @@ -0,0 +1,10 @@ +type: object +description: An inclusive query time window. +required: + - from + - to +properties: + from: + $ref: 'traces_time_instant.yml' + to: + $ref: 'traces_time_instant.yml' diff --git a/specification/resources/insights/models/traces_trace_response.yml b/specification/resources/insights/models/traces_trace_response.yml new file mode 100644 index 000000000..2da49cd05 --- /dev/null +++ b/specification/resources/insights/models/traces_trace_response.yml @@ -0,0 +1,12 @@ +type: object +description: A single trace and all of its spans. +properties: + trace_id: + type: string + description: The trace identifier. + example: "4bf92f3577b34da6a3ce929d0e0e4736" + spans: + type: array + description: Every span in the trace, ordered by start time. + items: + $ref: 'traces_span_record.yml' diff --git a/specification/resources/insights/models/traces_trace_summary.yml b/specification/resources/insights/models/traces_trace_summary.yml new file mode 100644 index 000000000..1bf13c872 --- /dev/null +++ b/specification/resources/insights/models/traces_trace_summary.yml @@ -0,0 +1,49 @@ +type: object +description: A single trace returned by a traces search. One row per trace, aggregated from its spans. +required: + - trace_id +properties: + trace_id: + type: string + description: The trace identifier. + example: "4bf92f3577b34da6a3ce929d0e0e4736" + started: + type: string + format: date-time + description: The start time of the earliest span in the trace. + example: "2026-09-30T00:14:12Z" + service_name: + type: string + description: The service that emitted the root span. + example: "api-gateway" + duration_ns: + type: string + format: int64 + description: Wall-clock duration of the trace in nanoseconds, encoded as a string to preserve 64-bit precision. + example: "154000000" + span_count: + type: integer + format: int32 + description: The number of spans in the trace. + example: 12 + error_count: + type: integer + format: int32 + description: The number of spans in the trace with an error status. + example: 1 + status: + type: string + description: The rolled-up status of the trace. `STATUS_CODE_ERROR` when any span errored. + example: "STATUS_CODE_ERROR" + span_names: + type: array + description: The distinct span names present in the trace. + items: + type: string + example: + - "GET /v2/droplets" + - "db.query" + region: + type: string + description: The datacenter region the trace was returned from. + example: nyc3 diff --git a/specification/resources/insights/parameters.yml b/specification/resources/insights/parameters.yml index a8238d184..a44369669 100644 --- a/specification/resources/insights/parameters.yml +++ b/specification/resources/insights/parameters.yml @@ -74,6 +74,15 @@ region: type: string example: nyc3 +trace_id: + in: path + name: trace_id + description: The hex-encoded identifier of the trace to retrieve. + required: true + schema: + type: string + example: 4bf92f3577b34da6a3ce929d0e0e4736 + label_name: in: path name: name diff --git a/specification/resources/insights/responses/trace.yml b/specification/resources/insights/responses/trace.yml new file mode 100644 index 000000000..fbef6847c --- /dev/null +++ b/specification/resources/insights/responses/trace.yml @@ -0,0 +1,14 @@ +description: The trace and its spans. + +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/traces_trace_response.yml' diff --git a/specification/resources/insights/responses/traces_search.yml b/specification/resources/insights/responses/traces_search.yml new file mode 100644 index 000000000..05140096e --- /dev/null +++ b/specification/resources/insights/responses/traces_search.yml @@ -0,0 +1,14 @@ +description: Traces search result. + +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/traces_search_response.yml' From 739ded4b737dc535473d4610f65bda94c6a0c958 Mon Sep 17 00:00:00 2001 From: Sakshi Rajput Date: Fri, 9 Oct 2026 13:02:04 +0530 Subject: [PATCH 2/4] COBS-1348: Use camelCase JSON to match live traces API --- .../examples/curl/insights_get_trace.yml | 2 +- .../curl/insights_post_tracesSearch.yml | 18 ++----- .../resources/insights/insights_get_trace.yml | 3 ++ .../insights/insights_post_tracesSearch.yml | 6 ++- .../insights/models/traces_field_ref.yml | 14 +++--- .../models/traces_filter_expression.yml | 2 +- .../insights/models/traces_filter_value.yml | 10 ++-- .../models/traces_pagination_request.yml | 2 +- .../models/traces_pagination_response.yml | 4 +- .../insights/models/traces_search_request.yml | 6 +-- .../models/traces_search_response.yml | 2 +- .../insights/models/traces_span_record.yml | 48 +++++++++---------- .../insights/models/traces_time_instant.yml | 7 +-- .../insights/models/traces_time_range.yml | 2 +- .../insights/models/traces_trace_response.yml | 9 +++- .../insights/models/traces_trace_summary.yml | 26 +++++----- 16 files changed, 77 insertions(+), 84 deletions(-) diff --git a/specification/resources/insights/examples/curl/insights_get_trace.yml b/specification/resources/insights/examples/curl/insights_get_trace.yml index d34b16321..e51b41095 100644 --- a/specification/resources/insights/examples/curl/insights_get_trace.yml +++ b/specification/resources/insights/examples/curl/insights_get_trace.yml @@ -2,4 +2,4 @@ lang: cURL source: |- curl -X GET \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ - "https://api.digitalocean.com/v2/insights/query/nyc3/traces/4bf92f3577b34da6a3ce929d0e0e4736" + "https://api.digitalocean.com/v2/insights/query/nyc3/traces/7b0b4e56abab38362b24e5498eb9ec64" diff --git a/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml b/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml index b5c144ff5..986e80e7b 100644 --- a/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml +++ b/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml @@ -4,20 +4,10 @@ source: |- -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ - "time_range": { - "from": {"absolute": "2026-09-30T00:00:00Z"}, - "to": {"absolute": "2026-09-30T01:00:00Z"} + "timeRange": { + "from": {"relative": "15m"}, + "to": {"relative": "now"} }, - "filter": { - "condition": { - "field": {"name": "service.name"}, - "operator": "FILTER_OPERATOR_EQ", - "value": {"string_value": "api-gateway"} - } - }, - "order_by": [ - {"field": {"name": "started"}, "direction": "SORT_DIRECTION_DESC"} - ], - "pagination": {"limit": 100} + "pagination": {"limit": 50} }' \ "https://api.digitalocean.com/v2/insights/query/nyc3/traces/search" diff --git a/specification/resources/insights/insights_get_trace.yml b/specification/resources/insights/insights_get_trace.yml index 416273a8c..8a09a1e7c 100644 --- a/specification/resources/insights/insights_get_trace.yml +++ b/specification/resources/insights/insights_get_trace.yml @@ -9,6 +9,9 @@ description: >- Spans are returned ordered by start time. A trace is only resolvable in the region that ingested it; querying another region returns `404`. + JSON field names are camelCase (`traceId`, `spanId`, `startTime`, `endTime`, + `durationNs`, `serviceName`, `statusCode`, `parentSpanId`). + tags: - Insights diff --git a/specification/resources/insights/insights_post_tracesSearch.yml b/specification/resources/insights/insights_post_tracesSearch.yml index 11d444072..69e5a5379 100644 --- a/specification/resources/insights/insights_post_tracesSearch.yml +++ b/specification/resources/insights/insights_post_tracesSearch.yml @@ -8,8 +8,10 @@ description: >- time range, optional filter, ordering, and pagination. Each result is one trace, aggregated from its spans. The time range must not - exceed 7 days. `pagination.limit` defaults to 100 and is clamped to 1000. - Results are ordered by `started` descending unless `order_by` is set. + exceed 7 days (`168h`). `pagination.limit` defaults to 100 and is clamped to + 1000. Results are ordered by `started` descending unless `orderBy` is set. + + JSON field names are camelCase (`timeRange`, `hasMore`, `traceId`). tags: - Insights diff --git a/specification/resources/insights/models/traces_field_ref.yml b/specification/resources/insights/models/traces_field_ref.yml index 226d49a2f..d806a72b1 100644 --- a/specification/resources/insights/models/traces_field_ref.yml +++ b/specification/resources/insights/models/traces_field_ref.yml @@ -6,13 +6,13 @@ properties: name: type: string description: >- - The field name. Intrinsic span columns include `trace_id`, `span_id`, - `parent_span_id`, `start_time`, `end_time`, `duration_ns`, `name`, - `kind`, `status_code`, and `status_message`. Trace-level columns include - `started`, `duration_ns`, `span_count`, `error_count`, and `status`. The - dotted shorthands `service.name`, `resource.type`, and `resource.urn` are - also supported. Arbitrary resource or span attributes can be accessed - with `ResourceAttributes['key']` or `SpanAttributes['key']`. + The field name. Intrinsic span columns include `traceId`, `spanId`, + `parentSpanId`, `startTime`, `endTime`, `durationNs`, `name`, `kind`, + `statusCode`, and `statusMessage`. Trace-level columns include `started`, + `durationNs`, `spanCount`, `errorCount`, and `status`. The dotted + shorthands `service.name`, `resource.type`, and `resource.urn` are also + supported. Arbitrary resource or span attributes can be accessed with + `ResourceAttributes['key']` or `SpanAttributes['key']`. example: service.name scope: type: string diff --git a/specification/resources/insights/models/traces_filter_expression.yml b/specification/resources/insights/models/traces_filter_expression.yml index 65b4e5507..126d4cacb 100644 --- a/specification/resources/insights/models/traces_filter_expression.yml +++ b/specification/resources/insights/models/traces_filter_expression.yml @@ -25,7 +25,7 @@ properties: $ref: 'traces_filter_expression.yml' not: $ref: 'traces_filter_expression.yml' - text_search: + textSearch: type: object description: A substring search across the span name, service name, and resource URN. required: diff --git a/specification/resources/insights/models/traces_filter_value.yml b/specification/resources/insights/models/traces_filter_value.yml index d917c99c2..86fdfe531 100644 --- a/specification/resources/insights/models/traces_filter_value.yml +++ b/specification/resources/insights/models/traces_filter_value.yml @@ -3,16 +3,16 @@ description: A typed literal or list value for a filter condition. Exactly one k minProperties: 1 maxProperties: 1 properties: - string_value: + stringValue: type: string example: "api-gateway" - number_value: + numberValue: type: number example: 42 - bool_value: + boolValue: type: boolean example: true - string_array_value: + stringArrayValue: type: object required: - values @@ -25,7 +25,7 @@ properties: example: - "api-gateway" - "auth-service" - number_array_value: + numberArrayValue: type: object required: - values diff --git a/specification/resources/insights/models/traces_pagination_request.yml b/specification/resources/insights/models/traces_pagination_request.yml index d7f2790dc..c75e0b729 100644 --- a/specification/resources/insights/models/traces_pagination_request.yml +++ b/specification/resources/insights/models/traces_pagination_request.yml @@ -8,4 +8,4 @@ properties: default: 100 minimum: 1 maximum: 1000 - example: 100 + example: 50 diff --git a/specification/resources/insights/models/traces_pagination_response.yml b/specification/resources/insights/models/traces_pagination_response.yml index 33c33debf..2daa8d21f 100644 --- a/specification/resources/insights/models/traces_pagination_response.yml +++ b/specification/resources/insights/models/traces_pagination_response.yml @@ -1,7 +1,7 @@ type: object description: Pagination response. properties: - has_more: + hasMore: type: boolean description: Whether more results matched the query than were returned. - example: true + example: false diff --git a/specification/resources/insights/models/traces_search_request.yml b/specification/resources/insights/models/traces_search_request.yml index 11418d5df..5f02d10fb 100644 --- a/specification/resources/insights/models/traces_search_request.yml +++ b/specification/resources/insights/models/traces_search_request.yml @@ -1,13 +1,13 @@ type: object description: Request body for searching traces. required: - - time_range + - timeRange properties: - time_range: + timeRange: $ref: 'traces_time_range.yml' filter: $ref: 'traces_filter_expression.yml' - order_by: + orderBy: type: array description: Sort clauses applied to the result set. Defaults to `started` descending. items: diff --git a/specification/resources/insights/models/traces_search_response.yml b/specification/resources/insights/models/traces_search_response.yml index eb730e674..20a9788f1 100644 --- a/specification/resources/insights/models/traces_search_response.yml +++ b/specification/resources/insights/models/traces_search_response.yml @@ -3,7 +3,7 @@ description: Response body for a traces search. properties: data: type: array - description: Matching traces. Omitted when no traces match. + description: Matching traces. Empty when no traces match. items: $ref: 'traces_trace_summary.yml' pagination: diff --git a/specification/resources/insights/models/traces_span_record.yml b/specification/resources/insights/models/traces_span_record.yml index eb9b351a4..680ad29d3 100644 --- a/specification/resources/insights/models/traces_span_record.yml +++ b/specification/resources/insights/models/traces_span_record.yml @@ -1,64 +1,63 @@ type: object description: A single span belonging to a trace. required: - - trace_id - - span_id + - traceId + - spanId properties: - trace_id: + traceId: type: string description: The trace this span belongs to. - example: "4bf92f3577b34da6a3ce929d0e0e4736" - span_id: + example: "7b0b4e56abab38362b24e5498eb9ec64" + spanId: type: string description: The span identifier. - example: "00f067aa0ba902b7" - parent_span_id: + example: "e7867486e45cda47" + parentSpanId: type: string description: The parent span identifier. Omitted for the root span. example: "a2fb4a1d1a96d312" - start_time: + startTime: type: string format: date-time description: The span start time. - example: "2026-09-30T00:14:12Z" - end_time: + example: "2026-10-09T06:44:37Z" + endTime: type: string format: date-time description: The span end time. - example: "2026-09-30T00:14:12.154Z" - duration_ns: - type: string + example: "2026-10-09T06:44:39Z" + durationNs: + type: integer format: int64 - description: Span duration in nanoseconds, encoded as a string to preserve 64-bit precision. - example: "154000000" + description: Span duration in nanoseconds. + example: 200000000 name: type: string description: The span name, typically the operation being performed. - example: "GET /v2/droplets" + example: "GET /smoke" kind: type: string description: The OpenTelemetry span kind. - example: "SPAN_KIND_SERVER" - status_code: + example: "Server" + statusCode: type: string description: The OpenTelemetry span status code. - example: "STATUS_CODE_ERROR" - status_message: + example: "Ok" + statusMessage: type: string description: The status description. Omitted when empty. example: "upstream timeout" - service_name: + serviceName: type: string description: The service that emitted the span. - example: "api-gateway" + example: "spans-spec-smoke" resource: type: object description: Resource attributes associated with the span. additionalProperties: type: string example: - do.component: "droplet" - do.droplet.id: "12345678" + service.name: "spans-spec-smoke" attributes: type: object description: Span attributes. @@ -66,7 +65,6 @@ properties: type: string example: http.method: "GET" - http.status_code: "504" region: type: string description: The datacenter region the span was returned from. diff --git a/specification/resources/insights/models/traces_time_instant.yml b/specification/resources/insights/models/traces_time_instant.yml index 15401b54d..f36163c47 100644 --- a/specification/resources/insights/models/traces_time_instant.yml +++ b/specification/resources/insights/models/traces_time_instant.yml @@ -16,9 +16,4 @@ properties: A relative time. Use `now` for the current time, a bare duration such as `1h` or `7d` to look back from now, or an offset such as `now-1h` or `now+30m`. Supported units are `s`, `m`, `h`, `d`, and `w`. - example: "1h" - unix_nano: - type: string - format: int64 - description: A Unix nanosecond timestamp, encoded as a string to preserve 64-bit precision. - example: "1756684800000000000" + example: "15m" diff --git a/specification/resources/insights/models/traces_time_range.yml b/specification/resources/insights/models/traces_time_range.yml index 9828f3b2e..bfd60b5f7 100644 --- a/specification/resources/insights/models/traces_time_range.yml +++ b/specification/resources/insights/models/traces_time_range.yml @@ -1,5 +1,5 @@ type: object -description: An inclusive query time window. +description: An inclusive query time window. Must not exceed 7 days (168h). required: - from - to diff --git a/specification/resources/insights/models/traces_trace_response.yml b/specification/resources/insights/models/traces_trace_response.yml index 2da49cd05..fceeef791 100644 --- a/specification/resources/insights/models/traces_trace_response.yml +++ b/specification/resources/insights/models/traces_trace_response.yml @@ -1,12 +1,17 @@ type: object description: A single trace and all of its spans. properties: - trace_id: + traceId: type: string description: The trace identifier. - example: "4bf92f3577b34da6a3ce929d0e0e4736" + example: "7b0b4e56abab38362b24e5498eb9ec64" spans: type: array description: Every span in the trace, ordered by start time. items: $ref: 'traces_span_record.yml' + truncated: + type: boolean + description: >- + True when the trace has more spans than were returned in this response. + example: false diff --git a/specification/resources/insights/models/traces_trace_summary.yml b/specification/resources/insights/models/traces_trace_summary.yml index 1bf13c872..7098b1db7 100644 --- a/specification/resources/insights/models/traces_trace_summary.yml +++ b/specification/resources/insights/models/traces_trace_summary.yml @@ -1,41 +1,41 @@ type: object description: A single trace returned by a traces search. One row per trace, aggregated from its spans. required: - - trace_id + - traceId properties: - trace_id: + traceId: type: string description: The trace identifier. - example: "4bf92f3577b34da6a3ce929d0e0e4736" + example: "7b0b4e56abab38362b24e5498eb9ec64" started: type: string format: date-time description: The start time of the earliest span in the trace. example: "2026-09-30T00:14:12Z" - service_name: + serviceName: type: string description: The service that emitted the root span. example: "api-gateway" - duration_ns: - type: string + durationNs: + type: integer format: int64 - description: Wall-clock duration of the trace in nanoseconds, encoded as a string to preserve 64-bit precision. - example: "154000000" - span_count: + description: Wall-clock duration of the trace in nanoseconds. + example: 154000000 + spanCount: type: integer format: int32 description: The number of spans in the trace. example: 12 - error_count: + errorCount: type: integer format: int32 description: The number of spans in the trace with an error status. example: 1 status: type: string - description: The rolled-up status of the trace. `STATUS_CODE_ERROR` when any span errored. - example: "STATUS_CODE_ERROR" - span_names: + description: The rolled-up status of the trace. + example: "Ok" + spanNames: type: array description: The distinct span names present in the trace. items: From 0cb238cc0a977dce84a92019080d0965a5db9d0b Mon Sep 17 00:00:00 2001 From: Sakshi Rajput Date: Fri, 9 Oct 2026 14:54:12 +0530 Subject: [PATCH 3/4] insights traces: match live search response fields --- .../models/traces_pagination_response.yml | 2 ++ .../models/traces_search_response.yml | 3 ++ .../insights/models/traces_trace_summary.yml | 35 ++++++++++++------- .../insights/responses/traces_search.yml | 12 +++++++ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/specification/resources/insights/models/traces_pagination_response.yml b/specification/resources/insights/models/traces_pagination_response.yml index 2daa8d21f..a41c12440 100644 --- a/specification/resources/insights/models/traces_pagination_response.yml +++ b/specification/resources/insights/models/traces_pagination_response.yml @@ -1,5 +1,7 @@ type: object description: Pagination response. +required: + - hasMore properties: hasMore: type: boolean diff --git a/specification/resources/insights/models/traces_search_response.yml b/specification/resources/insights/models/traces_search_response.yml index 20a9788f1..2fc6b4a40 100644 --- a/specification/resources/insights/models/traces_search_response.yml +++ b/specification/resources/insights/models/traces_search_response.yml @@ -1,5 +1,8 @@ type: object description: Response body for a traces search. +required: + - data + - pagination properties: data: type: array diff --git a/specification/resources/insights/models/traces_trace_summary.yml b/specification/resources/insights/models/traces_trace_summary.yml index 7098b1db7..6b3366ea6 100644 --- a/specification/resources/insights/models/traces_trace_summary.yml +++ b/specification/resources/insights/models/traces_trace_summary.yml @@ -1,39 +1,49 @@ type: object -description: A single trace returned by a traces search. One row per trace, aggregated from its spans. +description: >- + A single trace returned by a traces search. One row per trace, aggregated + from its spans. Every field except `traceId` is omitted when it holds its + zero value (for example, `errorCount` is absent when no spans errored). required: - traceId properties: traceId: type: string description: The trace identifier. - example: "7b0b4e56abab38362b24e5498eb9ec64" + example: "bef35030c4024f42fb88041fea062e97" started: type: string format: date-time - description: The start time of the earliest span in the trace. - example: "2026-09-30T00:14:12Z" + description: The start time of the earliest span in the trace, in RFC 3339 format. + example: "2026-10-09T09:21:39.99Z" serviceName: type: string description: The service that emitted the root span. - example: "api-gateway" + example: "sakshi-openapi-smoke" durationNs: type: integer format: int64 description: Wall-clock duration of the trace in nanoseconds. - example: 154000000 + example: 10000000 spanCount: type: integer format: int32 description: The number of spans in the trace. - example: 12 + example: 1 errorCount: type: integer format: int32 - description: The number of spans in the trace with an error status. + description: >- + The number of spans in the trace with an `Error` status code. Omitted + when zero. example: 1 status: type: string - description: The rolled-up status of the trace. + description: >- + The rolled-up status of the trace. `Error` if any span has an `Error` + status code, otherwise `Ok`. + enum: + - Ok + - Error example: "Ok" spanNames: type: array @@ -41,9 +51,10 @@ properties: items: type: string example: - - "GET /v2/droplets" - - "db.query" + - "sakshi-openapi-smoke-root" region: type: string - description: The datacenter region the trace was returned from. + description: >- + The datacenter region the trace was returned from. Only set on + multi-region searches; omitted from single-region responses. example: nyc3 diff --git a/specification/resources/insights/responses/traces_search.yml b/specification/resources/insights/responses/traces_search.yml index 05140096e..57f2182b1 100644 --- a/specification/resources/insights/responses/traces_search.yml +++ b/specification/resources/insights/responses/traces_search.yml @@ -12,3 +12,15 @@ content: application/json: schema: $ref: '../models/traces_search_response.yml' + example: + data: + - traceId: "bef35030c4024f42fb88041fea062e97" + started: "2026-10-09T09:21:39.99Z" + serviceName: "sakshi-openapi-smoke" + durationNs: 10000000 + status: "Ok" + spanCount: 1 + spanNames: + - "sakshi-openapi-smoke-root" + pagination: + hasMore: false From 5acbabb4badcf9a4dd0c553be231dc9d5958d3bb Mon Sep 17 00:00:00 2001 From: Sakshi Rajput Date: Fri, 9 Oct 2026 16:01:32 +0530 Subject: [PATCH 4/4] insights traces: match live request schema and errors - flat filter expressions (type/expressions/field/operator/value/query), lowercase operators - orderBy direction asc/desc; pagination limit 0-1000 (0 = default 100), no cursor - time instants accept RFC3339 or unix timestamps; GET supports from/to (default 7d) - document text/plain service errors (400/404/502) vs JSON edge errors (401/403/404/429) - list supported regions, single-region only, 60s timeout - drop region from trace/span models; neutral example names --- .../examples/curl/insights_get_trace.yml | 2 +- .../curl/insights_post_tracesSearch.yml | 10 +- .../resources/insights/insights_get_trace.yml | 33 ++++- .../insights/insights_post_tracesSearch.yml | 106 ++++++++++++++-- .../insights/models/traces_field_ref.yml | 42 +++++-- .../models/traces_filter_condition.yml | 21 ---- .../models/traces_filter_expression.yml | 115 ++++++++++++------ .../insights/models/traces_filter_value.yml | 95 ++++++++++----- .../insights/models/traces_order_by.yml | 24 +++- .../models/traces_pagination_request.yml | 13 +- .../insights/models/traces_search_request.yml | 5 +- .../insights/models/traces_span_record.yml | 26 ++-- .../insights/models/traces_time_instant.yml | 22 ++-- .../insights/models/traces_time_range.yml | 5 +- .../insights/models/traces_trace_response.yml | 1 + .../insights/models/traces_trace_summary.yml | 14 +-- .../resources/insights/parameters.yml | 32 ++++- .../insights/responses/traces_bad_gateway.yml | 17 +++ .../insights/responses/traces_bad_request.yml | 36 ++++++ .../insights/responses/traces_not_found.yml | 25 ++++ .../insights/responses/traces_search.yml | 4 +- 21 files changed, 491 insertions(+), 157 deletions(-) delete mode 100644 specification/resources/insights/models/traces_filter_condition.yml create mode 100644 specification/resources/insights/responses/traces_bad_gateway.yml create mode 100644 specification/resources/insights/responses/traces_bad_request.yml create mode 100644 specification/resources/insights/responses/traces_not_found.yml diff --git a/specification/resources/insights/examples/curl/insights_get_trace.yml b/specification/resources/insights/examples/curl/insights_get_trace.yml index e51b41095..e7a4f2e55 100644 --- a/specification/resources/insights/examples/curl/insights_get_trace.yml +++ b/specification/resources/insights/examples/curl/insights_get_trace.yml @@ -2,4 +2,4 @@ lang: cURL source: |- curl -X GET \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ - "https://api.digitalocean.com/v2/insights/query/nyc3/traces/7b0b4e56abab38362b24e5498eb9ec64" + "https://api.digitalocean.com/v2/insights/query/nyc3/traces/7b0b4e56abab38362b24e5498eb9ec64?from=24h&to=now" diff --git a/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml b/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml index 986e80e7b..54d80abb3 100644 --- a/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml +++ b/specification/resources/insights/examples/curl/insights_post_tracesSearch.yml @@ -5,9 +5,17 @@ source: |- -H "Content-Type: application/json" \ -d '{ "timeRange": { - "from": {"relative": "15m"}, + "from": {"relative": "24h"}, "to": {"relative": "now"} }, + "filter": { + "type": "and", + "expressions": [ + {"type": "condition", "field": {"name": "service.name"}, "operator": "eq", "value": "checkout-api"}, + {"type": "text_search", "query": "timeout"} + ] + }, + "orderBy": [{"field": {"name": "durationNs"}, "direction": "desc"}], "pagination": {"limit": 50} }' \ "https://api.digitalocean.com/v2/insights/query/nyc3/traces/search" diff --git a/specification/resources/insights/insights_get_trace.yml b/specification/resources/insights/insights_get_trace.yml index 8a09a1e7c..106adfa28 100644 --- a/specification/resources/insights/insights_get_trace.yml +++ b/specification/resources/insights/insights_get_trace.yml @@ -6,8 +6,28 @@ description: >- To retrieve a single trace and all of its spans, send a GET request to `/v2/insights/query/{region}/traces/{trace_id}`. - Spans are returned ordered by start time. A trace is only resolvable in the - region that ingested it; querying another region returns `404`. + Only spans that started within the lookup window are returned. The window + defaults to the last 7 days and can be narrowed with the `from` and `to` + query parameters; it must not exceed 7 days, and `from` must not be after + `to`. Spans are returned ordered by start time. At most 10,000 spans are + returned; `truncated` is `true` when the trace has more. + + A trace ID with no spans in the window returns `404`, as do malformed or + uppercase trace IDs. A trace is only resolvable in the region that ingested + it; querying another region also returns `404`. + + Supported regions are `ams2`, `ams3`, `atl1`, `blr1`, `fra1`, `lon1`, + `mem1`, `nyc1`, `nyc2`, `nyc3`, `ric1`, `sfo1`, `sfo2`, `sfo3`, `sgp1`, + `syd1`, and `tor1`. Requests time out after 60 seconds. + + Errors produced by the traces service (`400`, and `404` when no trace is + found) have a `text/plain` body containing a short message. Authentication + and authorization errors (`401`, `403`), rate limiting (`429`), and routing + errors (for example, `404` for an unknown region) come from the API gateway + and use the standard JSON error object with `id` and `message`. `403` is + also returned for accounts that are in a trial or not in good standing. If + the regional traces backend cannot be reached, the response is `502` with a + `text/plain` body. JSON field names are camelCase (`traceId`, `spanId`, `startTime`, `endTime`, `durationNs`, `serviceName`, `statusCode`, `parentSpanId`). @@ -18,13 +38,15 @@ tags: parameters: - $ref: 'parameters.yml#/region' - $ref: 'parameters.yml#/trace_id' + - $ref: 'parameters.yml#/trace_from' + - $ref: 'parameters.yml#/trace_to' responses: '200': $ref: 'responses/trace.yml' '400': - $ref: '../../shared/responses/bad_request.yml' + $ref: 'responses/traces_bad_request.yml' '401': $ref: '../../shared/responses/unauthorized.yml' @@ -33,7 +55,7 @@ responses: $ref: '../../shared/responses/forbidden.yml' '404': - $ref: '../../shared/responses/not_found.yml' + $ref: 'responses/traces_not_found.yml' '429': $ref: '../../shared/responses/too_many_requests.yml' @@ -41,6 +63,9 @@ responses: '500': $ref: '../../shared/responses/server_error.yml' + '502': + $ref: 'responses/traces_bad_gateway.yml' + default: $ref: '../../shared/responses/unexpected_error.yml' diff --git a/specification/resources/insights/insights_post_tracesSearch.yml b/specification/resources/insights/insights_post_tracesSearch.yml index 69e5a5379..a1f8b753a 100644 --- a/specification/resources/insights/insights_post_tracesSearch.yml +++ b/specification/resources/insights/insights_post_tracesSearch.yml @@ -7,11 +7,30 @@ description: >- `/v2/insights/query/{region}/traces/search` with a JSON body describing the time range, optional filter, ordering, and pagination. - Each result is one trace, aggregated from its spans. The time range must not - exceed 7 days (`168h`). `pagination.limit` defaults to 100 and is clamped to - 1000. Results are ordered by `started` descending unless `orderBy` is set. - - JSON field names are camelCase (`timeRange`, `hasMore`, `traceId`). + Each result is one trace, aggregated from all of its spans in the time + range. A trace is included when at least one of its spans matches + `filter`. The time range must not exceed 7 days (`168h`). + `pagination.limit` defaults to 100 (also used when `limit` is `0`) and must + be between 0 and 1000. Results are ordered by `started` descending unless + `orderBy` is set. + + JSON field names are camelCase (`timeRange`, `orderBy`, `hasMore`, + `traceId`). Unknown request properties, invalid filters, and out-of-range + values are rejected with `400`. + + Each request searches a single region; there is no multi-region search. + Supported regions are `ams2`, `ams3`, `atl1`, `blr1`, `fra1`, `lon1`, + `mem1`, `nyc1`, `nyc2`, `nyc3`, `ric1`, `sfo1`, `sfo2`, `sfo3`, `sgp1`, + `syd1`, and `tor1`. Requests time out after 60 seconds. + + Errors produced by the traces service (`400`) have a `text/plain` body + containing a short message. Authentication and authorization errors + (`401`, `403`), rate limiting (`429`), and routing errors (for example, + `404` for an unknown region) come from the API gateway and use the standard + JSON error object with `id` and `message`. `403` is also returned for + accounts that are in a trial or not in good standing. If the regional + traces backend cannot be reached, the response is `502` with a + `text/plain` body. tags: - Insights @@ -25,13 +44,83 @@ requestBody: application/json: schema: $ref: 'models/traces_search_request.yml' + examples: + recent: + summary: Most recent traces in the last 15 minutes + value: + timeRange: + from: + relative: 15m + to: + relative: now + pagination: + limit: 50 + filtered: + summary: Traces from one service whose spans mention "timeout" + value: + timeRange: + from: + relative: 24h + to: + relative: now + filter: + type: and + expressions: + - type: condition + field: + name: service.name + operator: eq + value: checkout-api + - type: text_search + query: timeout + pagination: + limit: 100 + attributeIn: + summary: Traces with error spans from either of two hosts + value: + timeRange: + from: + absolute: "2026-10-09T00:00:00Z" + to: + absolute: "2026-10-09T06:00:00Z" + filter: + type: and + expressions: + - field: + name: statusCode + operator: eq + value: Error + - field: + name: host.name + scope: resource + operator: in + value: + - web-01 + - web-02 + ordered: + summary: Slowest traces first, ties broken by oldest start + value: + timeRange: + from: + relative: 1h + to: + relative: now + orderBy: + - field: + name: durationNs + direction: desc + - field: + name: started + direction: asc + pagination: + limit: 20 responses: '200': $ref: 'responses/traces_search.yml' '400': - $ref: '../../shared/responses/bad_request.yml' + $ref: 'responses/traces_bad_request.yml' '401': $ref: '../../shared/responses/unauthorized.yml' @@ -40,7 +129,7 @@ responses: $ref: '../../shared/responses/forbidden.yml' '404': - $ref: '../../shared/responses/not_found.yml' + $ref: 'responses/traces_not_found.yml' '429': $ref: '../../shared/responses/too_many_requests.yml' @@ -48,6 +137,9 @@ responses: '500': $ref: '../../shared/responses/server_error.yml' + '502': + $ref: 'responses/traces_bad_gateway.yml' + default: $ref: '../../shared/responses/unexpected_error.yml' diff --git a/specification/resources/insights/models/traces_field_ref.yml b/specification/resources/insights/models/traces_field_ref.yml index d806a72b1..6064c4d10 100644 --- a/specification/resources/insights/models/traces_field_ref.yml +++ b/specification/resources/insights/models/traces_field_ref.yml @@ -1,23 +1,41 @@ type: object -description: A reference to a logical field for filters or ordering. +description: A reference to a span field, used in filters and `orderBy`. +additionalProperties: false required: - name properties: name: type: string description: >- - The field name. Intrinsic span columns include `traceId`, `spanId`, - `parentSpanId`, `startTime`, `endTime`, `durationNs`, `name`, `kind`, - `statusCode`, and `statusMessage`. Trace-level columns include `started`, - `durationNs`, `spanCount`, `errorCount`, and `status`. The dotted - shorthands `service.name`, `resource.type`, and `resource.urn` are also - supported. Arbitrary resource or span attributes can be accessed with - `ResourceAttributes['key']` or `SpanAttributes['key']`. + The field name. Without `scope`, these names (case-insensitive) resolve + to built-in span columns: `traceId` (`trace.id`, `trace_id`), `spanId` + (`span.id`, `span_id`), `parentSpanId` (`parent.span.id`, + `parent_span_id`), `startTime` (`start_time`, `timestamp`), `endTime` + (`end_time`), `durationNs` (`duration`, in nanoseconds), `name` + (`span.name`), `kind` (`span.kind`), `statusCode` (`status.code`, + `status_code`), `statusMessage` (`status.message`, `status_message`), + and `serviceName` (`service.name`, `service_name`). Any other name is + looked up as a span attribute, falling back to a resource attribute. + With `scope` set, `name` is always treated as an attribute key. + Attribute keys may contain only letters, digits, and `.`, `_`, `-`, + `/`, `:`, `@`. + + + In traces `orderBy`, `name` must be a trace-level sort field instead; + see the `orderBy` field description. example: service.name scope: type: string - description: The attribute scope to resolve the field against. Omit to let the server apply its default mapping for the field name. + description: >- + Restricts the lookup to one attribute map (case-insensitive). + `resource` (or `resource.attributes`) reads resource attributes; + `attribute` (or `attributes`, `span.attributes`) reads span attributes. + Omit to use the built-in column mapping described for `name`. Ignored + in traces `orderBy`. enum: - - FIELD_SCOPE_RESOURCE - - FIELD_SCOPE_ATTRIBUTES - example: FIELD_SCOPE_RESOURCE + - resource + - resource.attributes + - attribute + - attributes + - span.attributes + example: resource diff --git a/specification/resources/insights/models/traces_filter_condition.yml b/specification/resources/insights/models/traces_filter_condition.yml deleted file mode 100644 index 6d0cae25f..000000000 --- a/specification/resources/insights/models/traces_filter_condition.yml +++ /dev/null @@ -1,21 +0,0 @@ -type: object -description: A single field comparison in a traces filter expression. -required: - - field - - operator -properties: - field: - $ref: 'traces_field_ref.yml' - operator: - type: string - description: The comparison operator. - enum: - - FILTER_OPERATOR_EQ - - FILTER_OPERATOR_NEQ - - FILTER_OPERATOR_IN - - FILTER_OPERATOR_EXISTS - - FILTER_OPERATOR_GTE - - FILTER_OPERATOR_LTE - example: FILTER_OPERATOR_EQ - value: - $ref: 'traces_filter_value.yml' diff --git a/specification/resources/insights/models/traces_filter_expression.yml b/specification/resources/insights/models/traces_filter_expression.yml index 126d4cacb..7bee5ec8a 100644 --- a/specification/resources/insights/models/traces_filter_expression.yml +++ b/specification/resources/insights/models/traces_filter_expression.yml @@ -1,37 +1,82 @@ type: object -description: A boolean filter tree for traces queries. Exactly one node is set per message. -minProperties: 1 -maxProperties: 1 +description: >- + A node in a traces filter tree. Every node is the same flat object; `type` + selects which other properties apply: + + - `condition` (default when `type` is omitted): compares `field` to `value` + using `operator`. + + - `and` / `or`: combines the nodes in `expressions` (1 to 32 children). + + - `not`: negates the single node in `expressions` (exactly one child). + + - `text_search`: case-insensitive substring match of `query` against the + span name, service name, and span status message. + + + A trace matches when at least one of its spans in the time range matches + the filter. Trees may be nested at most 16 levels deep and contain at most + 256 nodes in total. Unknown properties are rejected. +additionalProperties: false properties: - condition: - $ref: 'traces_filter_condition.yml' - and: - type: object - required: - - expressions - properties: - expressions: - type: array - items: - $ref: 'traces_filter_expression.yml' - or: - type: object - required: - - expressions - properties: - expressions: - type: array - items: - $ref: 'traces_filter_expression.yml' - not: - $ref: 'traces_filter_expression.yml' - textSearch: - type: object - description: A substring search across the span name, service name, and resource URN. - required: - - query - properties: - query: - type: string - description: The search string. - example: "checkout" + type: + type: string + description: The node type. Matching is case-insensitive. + enum: + - condition + - and + - or + - not + - text_search + default: condition + example: condition + expressions: + type: array + description: >- + Child nodes for `and`, `or`, and `not`. `and` and `or` accept 1 to 32 + children; `not` requires exactly one. + minItems: 1 + maxItems: 32 + items: + $ref: 'traces_filter_expression.yml' + field: + $ref: 'traces_field_ref.yml' + operator: + type: string + description: >- + The comparison operator for a `condition` node. Matching is + case-insensitive, and the symbol forms `=`, `!=`, `>`, `>=`, `<`, and + `<=` are accepted as aliases for `eq`, `neq`, `gt`, `gte`, `lt`, and + `lte`. `exists` matches spans where the field is present and non-empty + and ignores `value`. `in` requires an array `value` with 1 to 100 + entries. `neq` on string fields also matches spans where the field is + absent. + enum: + - eq + - neq + - in + - exists + - gt + - gte + - lt + - lte + example: eq + value: + $ref: 'traces_filter_value.yml' + query: + type: string + description: >- + The search string for a `text_search` node. Leading and trailing + whitespace is trimmed; the trimmed string must be non-empty. + maxLength: 256 + example: checkout +example: + type: and + expressions: + - type: condition + field: + name: service.name + operator: eq + value: checkout-api + - type: text_search + query: timeout diff --git a/specification/resources/insights/models/traces_filter_value.yml b/specification/resources/insights/models/traces_filter_value.yml index 86fdfe531..d03942efd 100644 --- a/specification/resources/insights/models/traces_filter_value.yml +++ b/specification/resources/insights/models/traces_filter_value.yml @@ -1,40 +1,73 @@ -type: object -description: A typed literal or list value for a filter condition. Exactly one kind is set per message. -minProperties: 1 -maxProperties: 1 -properties: - stringValue: - type: string - example: "api-gateway" - numberValue: - type: number - example: 42 - boolValue: - type: boolean +description: >- + The comparison value for a filter `condition`. Pass either a bare JSON + literal (string, number, boolean, or array for `in`) or a typed object + `{"type": "...", "value": ...}`. String values are coerced to the field's + type: numeric fields such as `durationNs` parse the string as a number, and + time fields such as `startTime` accept the same absolute formats as + `timeRange` (RFC3339 or Unix seconds/milliseconds/microseconds/nanoseconds). +example: checkout-api +oneOf: + - type: string + description: A bare string literal. + example: checkout-api + - type: number + description: A bare number literal. + example: 500000000 + - type: boolean + description: A bare boolean literal. example: true - stringArrayValue: - type: object + - type: array + description: A bare array of values, used with the `in` operator. + minItems: 1 + maxItems: 100 + items: + oneOf: + - type: string + - type: number + - type: boolean + example: + - checkout-api + - payments-api + - type: object + description: >- + A typed scalar value. `type` is case-insensitive; `int`, `integer`, and + `float` are accepted as aliases for `number`, and `boolean` for `bool`. + additionalProperties: false required: - - values + - type + - value properties: - values: - type: array - minItems: 1 - items: - type: string - example: - - "api-gateway" - - "auth-service" - numberArrayValue: - type: object + type: + type: string + enum: + - string + - number + - bool + example: number + value: + oneOf: + - type: string + - type: number + - type: boolean + example: 500000000 + - type: object + description: A typed string list, used with the `in` operator. + additionalProperties: false required: - - values + - type + - value properties: - values: + type: + type: string + enum: + - string_array + example: string_array + value: type: array minItems: 1 + maxItems: 100 items: - type: number + type: string example: - - 42 - - 84 + - checkout-api + - payments-api diff --git a/specification/resources/insights/models/traces_order_by.yml b/specification/resources/insights/models/traces_order_by.yml index 86ae2ff87..f6cce3541 100644 --- a/specification/resources/insights/models/traces_order_by.yml +++ b/specification/resources/insights/models/traces_order_by.yml @@ -1,5 +1,18 @@ type: object -description: A sort clause for traces search results. +description: >- + A sort clause for traces search results. Supported `field.name` values + (case-insensitive) are `started` (aliases `startTime`, `start_time`, + `timestamp`), `durationNs` (`duration`), `serviceName` (`service.name`, + `service_name`), `traceId` (`trace.id`, `trace_id`), `errorCount` + (`error_count`), `spanCount` (`span_count`), and `status`. Any other name + returns `400`. + + + Sorting by `started` is exact. For every other field, the server first + selects the most recent matching traces by start time (up to the requested + limit) and then sorts only those traces, so results are not a global top-N + across the whole time range. +additionalProperties: false required: - field properties: @@ -7,8 +20,9 @@ properties: $ref: 'traces_field_ref.yml' direction: type: string - description: The sort direction. Omit to use the server default. + description: The sort direction (case-insensitive). Defaults to `desc`. enum: - - SORT_DIRECTION_ASC - - SORT_DIRECTION_DESC - example: SORT_DIRECTION_DESC + - asc + - desc + default: desc + example: desc diff --git a/specification/resources/insights/models/traces_pagination_request.yml b/specification/resources/insights/models/traces_pagination_request.yml index c75e0b729..f668b142d 100644 --- a/specification/resources/insights/models/traces_pagination_request.yml +++ b/specification/resources/insights/models/traces_pagination_request.yml @@ -1,11 +1,18 @@ type: object -description: Limits the size of a traces search result set. +description: >- + Limits the size of a traces search result set. There is no cursor; use + `pagination.hasMore` in the response to tell whether more traces matched, + and narrow the time range or filter to see them. +additionalProperties: false properties: limit: type: integer format: int32 - description: Maximum number of results to return. Defaults to 100 and is clamped to 1000. + description: >- + Maximum number of traces to return. Omitted or `0` uses the default of + 100. Negative values or values above 1000 return `400`; they are not + clamped. default: 100 - minimum: 1 + minimum: 0 maximum: 1000 example: 50 diff --git a/specification/resources/insights/models/traces_search_request.yml b/specification/resources/insights/models/traces_search_request.yml index 5f02d10fb..dcd38069b 100644 --- a/specification/resources/insights/models/traces_search_request.yml +++ b/specification/resources/insights/models/traces_search_request.yml @@ -1,5 +1,6 @@ type: object -description: Request body for searching traces. +description: Request body for searching traces. Unknown properties are rejected. +additionalProperties: false required: - timeRange properties: @@ -9,7 +10,7 @@ properties: $ref: 'traces_filter_expression.yml' orderBy: type: array - description: Sort clauses applied to the result set. Defaults to `started` descending. + description: Sort clauses applied in order. Defaults to `started` descending. items: $ref: 'traces_order_by.yml' pagination: diff --git a/specification/resources/insights/models/traces_span_record.yml b/specification/resources/insights/models/traces_span_record.yml index 680ad29d3..523061224 100644 --- a/specification/resources/insights/models/traces_span_record.yml +++ b/specification/resources/insights/models/traces_span_record.yml @@ -34,38 +34,40 @@ properties: name: type: string description: The span name, typically the operation being performed. - example: "GET /smoke" + example: "GET /checkout" kind: type: string - description: The OpenTelemetry span kind. + description: >- + The OpenTelemetry span kind as a string, for example `Server`, + `Client`, or `Internal`. example: "Server" statusCode: type: string - description: The OpenTelemetry span status code. - example: "Ok" + description: >- + The OpenTelemetry span status code as a string: `Unset`, `Ok`, or + `Error`. + example: "Error" statusMessage: type: string description: The status description. Omitted when empty. example: "upstream timeout" serviceName: type: string - description: The service that emitted the span. - example: "spans-spec-smoke" + description: >- + The service that emitted the span. Omitted when the span has no + service.name resource attribute. + example: "checkout-api" resource: type: object description: Resource attributes associated with the span. additionalProperties: type: string example: - service.name: "spans-spec-smoke" + service.name: "checkout-api" attributes: type: object - description: Span attributes. + description: Span attributes. Omitted when empty. additionalProperties: type: string example: http.method: "GET" - region: - type: string - description: The datacenter region the span was returned from. - example: nyc3 diff --git a/specification/resources/insights/models/traces_time_instant.yml b/specification/resources/insights/models/traces_time_instant.yml index f36163c47..f35931dda 100644 --- a/specification/resources/insights/models/traces_time_instant.yml +++ b/specification/resources/insights/models/traces_time_instant.yml @@ -1,19 +1,23 @@ type: object -description: A single point in time. Exactly one value form is set per message. +description: >- + A single point in time. Set `absolute` or `relative`; if both are set, + `absolute` is used. +additionalProperties: false minProperties: 1 -maxProperties: 1 properties: absolute: type: string - format: date-time description: >- - An absolute timestamp. Accepts RFC3339/RFC3339Nano strings or Unix - seconds/nanoseconds as decimal strings. - example: "2026-09-01T00:00:00Z" + An absolute timestamp, either RFC3339 (with optional fractional + seconds) or a Unix epoch integer as a decimal string. Epoch precision + is inferred from magnitude: seconds, milliseconds, microseconds, or + nanoseconds. + example: "2026-10-09T00:00:00Z" relative: type: string description: >- - A relative time. Use `now` for the current time, a bare duration such as - `1h` or `7d` to look back from now, or an offset such as `now-1h` or - `now+30m`. Supported units are `s`, `m`, `h`, `d`, and `w`. + A time relative to now. Use `now` for the current time, a bare duration + such as `15m` or `24h` to look back from now, or an offset such as + `now-2h` or `now+30m`. Supported units are `s`, `m`, `h`, `d`, and `w`; + decimal amounts such as `1.5h` are allowed. example: "15m" diff --git a/specification/resources/insights/models/traces_time_range.yml b/specification/resources/insights/models/traces_time_range.yml index bfd60b5f7..b3e70de35 100644 --- a/specification/resources/insights/models/traces_time_range.yml +++ b/specification/resources/insights/models/traces_time_range.yml @@ -1,5 +1,8 @@ type: object -description: An inclusive query time window. Must not exceed 7 days (168h). +description: >- + An inclusive query time window. Both bounds are required, `from` must not + be after `to`, and the window must not exceed 7 days (`168h`). +additionalProperties: false required: - from - to diff --git a/specification/resources/insights/models/traces_trace_response.yml b/specification/resources/insights/models/traces_trace_response.yml index fceeef791..3f8744e78 100644 --- a/specification/resources/insights/models/traces_trace_response.yml +++ b/specification/resources/insights/models/traces_trace_response.yml @@ -14,4 +14,5 @@ properties: type: boolean description: >- True when the trace has more spans than were returned in this response. + Omitted when false. example: false diff --git a/specification/resources/insights/models/traces_trace_summary.yml b/specification/resources/insights/models/traces_trace_summary.yml index 6b3366ea6..5d7ffbe82 100644 --- a/specification/resources/insights/models/traces_trace_summary.yml +++ b/specification/resources/insights/models/traces_trace_summary.yml @@ -17,8 +17,10 @@ properties: example: "2026-10-09T09:21:39.99Z" serviceName: type: string - description: The service that emitted the root span. - example: "sakshi-openapi-smoke" + description: >- + The service that emitted the root span. Omitted when the root span has + no service.name resource attribute. + example: "checkout-api" durationNs: type: integer format: int64 @@ -51,10 +53,4 @@ properties: items: type: string example: - - "sakshi-openapi-smoke-root" - region: - type: string - description: >- - The datacenter region the trace was returned from. Only set on - multi-region searches; omitted from single-region responses. - example: nyc3 + - "checkout-api-root" diff --git a/specification/resources/insights/parameters.yml b/specification/resources/insights/parameters.yml index a44369669..fb98ecc42 100644 --- a/specification/resources/insights/parameters.yml +++ b/specification/resources/insights/parameters.yml @@ -77,11 +77,39 @@ region: trace_id: in: path name: trace_id - description: The hex-encoded identifier of the trace to retrieve. + description: >- + The OpenTelemetry trace ID to retrieve, as 32 lowercase hexadecimal + characters. IDs are matched exactly; an ID with no spans in the lookup + window returns `404`. Malformed or uppercase IDs are not rejected with + `400`; they also return `404`. required: true schema: type: string - example: 4bf92f3577b34da6a3ce929d0e0e4736 + example: 7b0b4e56abab38362b24e5498eb9ec64 + +trace_from: + in: query + name: from + required: false + description: >- + Start of the trace lookup window. Accepts a relative time (`now`, a bare + duration such as `24h` to look back from now, or `now-2h`) or an absolute + time (RFC3339, or a Unix epoch integer in seconds, milliseconds, + microseconds, or nanoseconds). Defaults to 7 days before now. + schema: + type: string + example: 24h + +trace_to: + in: query + name: to + required: false + description: >- + End of the trace lookup window, in the same formats as `from`. Defaults to + now. + schema: + type: string + example: now label_name: in: path diff --git a/specification/resources/insights/responses/traces_bad_gateway.yml b/specification/resources/insights/responses/traces_bad_gateway.yml new file mode 100644 index 000000000..9370642de --- /dev/null +++ b/specification/resources/insights/responses/traces_bad_gateway.yml @@ -0,0 +1,17 @@ +description: >- + The regional traces backend could not be reached. The body is a short + plain-text message. + +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: + text/plain: + schema: + type: string + example: Bad Gateway diff --git a/specification/resources/insights/responses/traces_bad_request.yml b/specification/resources/insights/responses/traces_bad_request.yml new file mode 100644 index 000000000..e3f7d1f55 --- /dev/null +++ b/specification/resources/insights/responses/traces_bad_request.yml @@ -0,0 +1,36 @@ +description: >- + The request was rejected by the traces service, for example because the + body is malformed, a field is out of range, or the time range is invalid. + The body is a short plain-text message. + +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: + text/plain: + schema: + type: string + examples: + limit_above_maximum: + summary: Pagination limit above maximum + value: pagination.limit exceeds maximum of 1000 + search_time_range_too_long: + summary: Search time range longer than 7 days + value: timeRange exceeds maximum of 168h0m0s + trace_window_too_long: + summary: Trace lookup window longer than 7 days + value: time range exceeds maximum of 168h0m0s + invalid_order_direction: + summary: Unsupported orderBy direction + value: invalid orderBy direction "SORT_DIRECTION_ASC" + from_after_to: + summary: Time range start after end + value: timeRange.from must be before or equal to timeRange.to + unknown_property: + summary: Unknown or malformed request body property + value: invalid request body diff --git a/specification/resources/insights/responses/traces_not_found.yml b/specification/resources/insights/responses/traces_not_found.yml new file mode 100644 index 000000000..fdaefe0ad --- /dev/null +++ b/specification/resources/insights/responses/traces_not_found.yml @@ -0,0 +1,25 @@ +description: >- + The trace or region was not found. When the traces service finds no + matching trace, the body is the plain-text message `trace not found`. When + the region is unknown or does not serve traces, the API gateway returns a + JSON error object. + +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: + text/plain: + schema: + type: string + example: trace not found + application/json: + schema: + $ref: '../../../shared/models/error.yml' + example: + id: not_found + message: Your request could not be routed. diff --git a/specification/resources/insights/responses/traces_search.yml b/specification/resources/insights/responses/traces_search.yml index 57f2182b1..6991e7d4d 100644 --- a/specification/resources/insights/responses/traces_search.yml +++ b/specification/resources/insights/responses/traces_search.yml @@ -16,11 +16,11 @@ content: data: - traceId: "bef35030c4024f42fb88041fea062e97" started: "2026-10-09T09:21:39.99Z" - serviceName: "sakshi-openapi-smoke" + serviceName: "checkout-api" durationNs: 10000000 status: "Ok" spanCount: 1 spanNames: - - "sakshi-openapi-smoke-root" + - "checkout-api-root" pagination: hasMore: false