Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions specification/DigitalOcean-public.v2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,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/insights/query/{region}/spans/search:
post:
$ref: "resources/insights/insights_post_spansSearch.yml"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lang: cURL
source: |-
curl -X GET \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
"https://api.digitalocean.com/v2/insights/query/nyc3/traces/7b0b4e56abab38362b24e5498eb9ec64?from=24h&to=now"
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
lang: cURL
source: |-
curl -X POST \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"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"}
]
},
"orderBy": [{"field": {"name": "durationNs"}, "direction": "desc"}],
"pagination": {"limit": 50}
}' \
"https://api.digitalocean.com/v2/insights/query/nyc3/traces/search"
77 changes: 77 additions & 0 deletions specification/resources/insights/insights_get_trace.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
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}`.

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`).

tags:
- Insights

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: 'responses/traces_bad_request.yml'

'401':
$ref: '../../shared/responses/unauthorized.yml'

'403':
$ref: '../../shared/responses/forbidden.yml'

'404':
$ref: 'responses/traces_not_found.yml'

'429':
$ref: '../../shared/responses/too_many_requests.yml'

'500':
$ref: '../../shared/responses/server_error.yml'

'502':
$ref: 'responses/traces_bad_gateway.yml'

default:
$ref: '../../shared/responses/unexpected_error.yml'

x-codeSamples:
- $ref: 'examples/curl/insights_get_trace.yml'

security:
- bearer_auth:
- 'insights:read'
151 changes: 151 additions & 0 deletions specification/resources/insights/insights_post_tracesSearch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
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 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

parameters:
- $ref: 'parameters.yml#/region'

requestBody:
required: true
content:
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: 'responses/traces_bad_request.yml'

'401':
$ref: '../../shared/responses/unauthorized.yml'

'403':
$ref: '../../shared/responses/forbidden.yml'

'404':
$ref: 'responses/traces_not_found.yml'

'429':
$ref: '../../shared/responses/too_many_requests.yml'

'500':
$ref: '../../shared/responses/server_error.yml'

'502':
$ref: 'responses/traces_bad_gateway.yml'

default:
$ref: '../../shared/responses/unexpected_error.yml'

x-codeSamples:
- $ref: 'examples/curl/insights_post_tracesSearch.yml'

security:
- bearer_auth:
- 'insights:read'
41 changes: 41 additions & 0 deletions specification/resources/insights/models/traces_field_ref.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
type: object
description: A reference to a span field, used in filters and `orderBy`.
additionalProperties: false
required:
- name
properties:
name:
type: string
description: >-
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: >-
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:
- resource
- resource.attributes
- attribute
- attributes
- span.attributes
example: resource
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
type: object
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:
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
Loading
Loading