Skip to content
Last9
Book demo

Traces Query API

Query and analyze distributed traces programmatically using the Last9 Traces API

The Traces Query API enables programmatic access to your distributed tracing data stored in Last9. Use these endpoints to query traces, search for spans, manage saved searches, and retrieve trace metadata.

Prerequisites

Before using the Traces Query API, you need:

  1. An API access token (see Getting started with API)
  2. Your organization slug
  3. Your data region (e.g., us-east-1)

Base URL

https://app.last9.io/api/v4/organizations/{org-slug}

Replace {org-slug} with your organization’s unique slug.

Authentication

All API endpoints require authentication via the X-LAST9-API-TOKEN header:

X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>

Query Traces

The primary endpoint for querying trace data with pipeline-based filtering.

POST /cat/api/traces/v2/query_range/json

Query Parameters

ParameterTypeRequiredDescription
regionstringYesYour data region (e.g., us-east-1)
startintegerYesStart time in Unix seconds
endintegerYesEnd time in Unix seconds
limitintegerNoMaximum number of results to return
orderstringNoSort order (asc or desc)
directionstringNoQuery direction
modestringNoQuery mode: span or trace

Request Body

The request body contains a pipeline array with filter stages:

{
"pipeline": [
{
"type": "filter",
"query": {
"$and": [
{ "$eq": ["service.name", "api-gateway"] },
{ "$gte": ["http.status_code", "500"] }
]
}
}
]
}

Example Request

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/query_range/json?region=us-east-1&start=1727083606&end=1727087206&limit=100&mode=trace" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"pipeline": [
{
"type": "filter",
"query": {
"$and": [
{ "$eq": ["service.name", "api-gateway"] }
]
}
}
]
}'

Response

{
"status": "success",
"data": {
"resultType": "stream",
"result": [
{
"Timestamp": "2024-09-23T09:45:13.700906028Z",
"TraceId": "cb9cd197d727655add1c12c4afe0b476",
"SpanId": "83fca378bb34f8db",
"ParentSpanId": "",
"SpanName": "GET /api/v1/users",
"SpanKind": "SPAN_KIND_SERVER",
"ServiceName": "api-gateway",
"ResourceAttributes": {
"service.name": "api-gateway",
"telemetry.sdk.name": "opentelemetry"
},
"SpanAttributes": {
"http.method": "GET",
"http.status_code": "200",
"http.target": "/api/v1/users"
},
"Duration": 25748892,
"StatusCode": "STATUS_CODE_UNSET",
"StatusMessage": ""
}
]
}
}

Search Traces

Search for traces matching specific criteria with span sets. This endpoint is useful for finding traces based on duration thresholds.

POST /cat/api/traces/v2/search/json

Query Parameters

ParameterTypeRequiredDescription
regionstringYesYour data region
startintegerYesStart time in Unix seconds
endintegerYesEnd time in Unix seconds
limitintegerNoMaximum number of traces to return
span_limitintegerNoMaximum spans per trace
orderstringNoSort order
modestringNoQuery mode: span or trace
minDurationstringNoMinimum duration filter (e.g., 100ms, 1s)
maxDurationstringNoMaximum duration filter (e.g., 5s, 10000ms)

Example Request

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/search/json?region=us-east-1&start=1727083606&end=1727087206&limit=50&minDuration=500ms" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"pipeline": []}'

Response

{
"status": "success",
"data": {
"resultType": "stream",
"result": [
{
"traceID": "7d7de75bd7d3d51cf29d73ad5e36a227",
"rootServiceName": "api-gateway",
"rootTraceName": "GET /api/v1/users",
"startTimeUnixNano": 1727083606684633211,
"endTimeUnixNano": 1727083606716391435,
"durationMs": 31.758224,
"spanSets": [
{
"matched": 1,
"spans": [...]
}
]
}
]
}
}

Get Trace by ID

Retrieve all spans for a specific trace.

GET /cat/api/traces/{traceID}

Path Parameters

ParameterTypeDescription
traceIDstringThe 32-character hex trace ID

Query Parameters

ParameterTypeRequiredDescription
regionstringYesYour data region
startintegerYesStart time in Unix seconds
endintegerYesEnd time in Unix seconds
limitintegerNoMaximum number of spans to return (default: 1000)

Example Request

curl -X GET \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/7d7de75bd7d3d51cf29d73ad5e36a227?region=us-east-1&start=1727083606&end=1727087206" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>"

Response

{
"traces": [
{
"Timestamp": "2024-09-23T09:45:13.700906028Z",
"TraceId": "cb9cd197d727655add1c12c4afe0b476",
"SpanId": "83fca378bb34f8db",
"ParentSpanId": "",
"TraceState": "",
"SpanName": "GET /api/v1/users",
"SpanKind": "SPAN_KIND_SERVER",
"ServiceName": "api-gateway",
"ResourceAttributes": {
"service.name": "api-gateway",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.4.1"
},
"ScopeName": "OpenTelemetry::Instrumentation::Rack",
"ScopeVersion": "0.24.5",
"SpanAttributes": {
"http.method": "GET",
"http.status_code": "200",
"http.target": "/api/v1/users"
},
"Duration": 25748892,
"StatusCode": "STATUS_CODE_UNSET",
"StatusMessage": "",
"EventsTimestamp": [],
"EventsName": [],
"EventsAttributes": [],
"LinksTraceId": [],
"LinksSpanId": [],
"LinksTraceState": [],
"LinksAttributes": []
}
]
}

Get Trace Heatmap

Retrieve a heatmap of trace durations over time for visualizing latency distribution.

POST /cat/api/traces/v2/heatmap/json

Query Parameters

ParameterTypeRequiredDescription
regionstringYesYour data region
startintegerYesStart time in Unix seconds
endintegerYesEnd time in Unix seconds
time_resolution_secintegerYesX-axis resolution in seconds
bucketsintegerYesY-axis resolution (number of duration buckets)

Example Request

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/heatmap/json?region=us-east-1&start=1727083606&end=1727087206&time_resolution_sec=60&buckets=20" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"pipeline": []}'

Response

{
"data": [
{
"timestamp": "2024-09-23T09:45:00Z",
"values": [
[10.5, 150],
[50.2, 230],
[100.8, 85]
]
}
]
}

Get Trace Tags

Retrieve available tags/labels for filtering traces.

POST /cat/api/traces/v2/series/json

Query Parameters

ParameterTypeRequiredDescription
regionstringYesYour data region
startintegerYesStart time in Unix seconds
endintegerYesEnd time in Unix seconds

Example Request

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/series/json?region=us-east-1&start=1727083606&end=1727087206" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{}'

Response

{
"status": "success",
"data": [
{
"service.name": "api-gateway",
"http.method": "GET"
}
]
}

Get Tag Values

Retrieve possible values for a specific tag.

POST /cat/api/traces/v2/label/json/{tagName}/values

Path Parameters

ParameterTypeDescription
tagNamestringThe tag name

Query Parameters

ParameterTypeRequiredDescription
regionstringYesYour data region
startintegerYesStart time in Unix seconds
endintegerYesEnd time in Unix seconds

Example Request

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/label/json/service.name/values?region=us-east-1&start=1727083606&end=1727087206" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{}'

Response

{
"status": "success",
"data": ["api-gateway", "user-service", "payment-service", "notification-service"]
}

Pipeline Syntax

The Traces API uses a JSON pipeline format for filtering trace data.

Filter Stage

{
"type": "filter",
"query": {
"$and": [
{ "$eq": ["field.name", "value"] },
{ "$gte": ["numeric.field", "100"] }
]
}
}

Filter Operators

OperatorDescriptionExample
$eqEqual (case-sensitive){"$eq": ["service.name", "api"]}
$ieqEqual (case-insensitive){"$ieq": ["service.name", "API"]}
$neqNot equal (case-sensitive){"$neq": ["status", "error"]}
$ineqNot equal (case-insensitive){"$ineq": ["status", "ERROR"]}
$gtGreater than{"$gt": ["duration", "1000"]}
$gteGreater than or equal{"$gte": ["http.status_code", "400"]}
$ltLess than{"$lt": ["duration", "5000"]}
$lteLess than or equal{"$lte": ["http.status_code", "499"]}
$containsContains substring (case-sensitive){"$contains": ["path", "/api"]}
$icontainsContains (case-insensitive){"$icontains": ["path", "/API"]}
$notcontainsDoes not contain (case-sensitive){"$notcontains": ["path", "health"]}
$regexMatches regex (case-sensitive){"$regex": ["path", "^/api/v[0-9]+"]}
$iregexMatches regex (case-insensitive){"$iregex": ["method", "get|post"]}
$notregexDoes not match regex{"$notregex": ["path", "internal"]}

Logical Operators

Combine conditions using $and, $or, and $not:

AND (All conditions must match)

{
"$and": [
{ "$eq": ["service.name", "api-gateway"] },
{ "$gte": ["http.status_code", "500"] }
]
}

OR (Any condition can match)

{
"$or": [
{ "$eq": ["http.status_code", "500"] },
{ "$eq": ["http.status_code", "502"] }
]
}

NOT (Negate conditions)

{
"$not": [
{ "$and": [
{ "$eq": ["service.name", "health-check"] }
]}
]
}

Combining Logical Operators

Nest logical operators to build complex queries:

{
"$and": [
{ "$eq": ["service.name", "api-gateway"] },
{ "$or": [
{ "$eq": ["http.status_code", "500"] },
{ "$eq": ["http.status_code", "502"] }
]}
]
}

Field Prefixes

PrefixDescriptionExample
resource.Resource-level attributesresource.service.name
span.Span-level attributesspan.http.method
(none)Auto-resolved based on attributeservice.name

Common Query Patterns

Filter by Service and Status Code

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/query_range/json?region=us-east-1&start=1727083606&end=1727087206&limit=100&mode=trace" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"pipeline": [
{
"type": "filter",
"query": {
"$and": [
{ "$eq": ["service.name", "api-gateway"] },
{ "$gte": ["http.status_code", "500"] }
]
}
}
]
}'

Duration-Based Filtering

Find slow traces using the Search endpoint’s duration parameters:

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/search/json?region=us-east-1&start=1727083606&end=1727087206&limit=50&minDuration=1s&maxDuration=10s" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"pipeline": []}'

Regex Pattern Matching

Match spans with paths following a pattern:

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/query_range/json?region=us-east-1&start=1727083606&end=1727087206&limit=100&mode=span" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"pipeline": [
{
"type": "filter",
"query": {
"$and": [
{ "$regex": ["http.target", "^/api/v[0-9]+/users"] }
]
}
}
]
}'

Multi-Condition with OR

Find error traces across multiple services:

curl -X POST \
"https://app.last9.io/api/v4/organizations/{org-slug}/cat/api/traces/v2/query_range/json?region=us-east-1&start=1727083606&end=1727087206&limit=100&mode=trace" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"pipeline": [
{
"type": "filter",
"query": {
"$and": [
{ "$or": [
{ "$eq": ["service.name", "api-gateway"] },
{ "$eq": ["service.name", "payment-service"] }
]},
{ "$gte": ["http.status_code", "500"] }
]
}
}
]
}'

Response Format

Success Response Structure

All query endpoints return a JSON envelope with a status field and a data object containing the results:

{
"status": "success",
"data": {
"resultType": "stream",
"result": [ ... ]
}
}

The shape of objects inside result varies by endpoint — see each endpoint’s Response section for details.

Empty Results

When no traces match your query, the result array will be empty:

{
"status": "success",
"data": {
"resultType": "stream",
"result": []
}
}

Reference

Trace Modes

ModeDescription
spanQuery and filter individual spans
traceQuery complete traces (groups of related spans)

Span Data Types

Span Kinds

ValueDescription
SPAN_KIND_UNSPECIFIEDUnspecified span kind
SPAN_KIND_INTERNALInternal operation within a service
SPAN_KIND_SERVERServer-side handling of an RPC request
SPAN_KIND_CLIENTClient-side of an RPC request
SPAN_KIND_PRODUCERProducer of an async message
SPAN_KIND_CONSUMERConsumer of an async message

Status Codes

ValueDescription
STATUS_CODE_UNSETStatus not set
STATUS_CODE_OKOperation completed successfully
STATUS_CODE_ERROROperation failed

Common Span Attributes

HTTP Attributes

AttributeDescription
http.methodHTTP method (GET, POST, etc.)
http.status_codeHTTP response status code
http.targetRequest target/path
http.hostRequest host
http.schemeURL scheme (http, https)
http.user_agentUser agent string

Database Attributes

AttributeDescription
db.systemDatabase type (mysql, postgres, redis)
db.nameDatabase name
db.statementDatabase query/statement

Network Attributes

AttributeDescription
net.peer.nameRemote hostname/IP
net.peer.portRemote port

Code Attributes

AttributeDescription
code.functionFunction/method name
code.namespaceCode namespace/class

Saved Searches

Manage saved trace searches for your organization.

List Saved Searches

GET /traces/searches

Query Parameters

ParameterTypeRequiredDescription
query_sourcestringNoFilter by source: manual or nlp

Example Request

curl -X GET \
"https://app.last9.io/api/v4/organizations/{org-slug}/traces/searches" \
-H "X-LAST9-API-TOKEN: Bearer <ACCESS_TOKEN>"
POST /traces/searches

Request Body

{
"name": "Error Traces",
"pipeline": [
{
"type": "filter",
"query": {
"$and": [
{ "$gte": ["http.status_code", "500"] }
]
}
}
],
"mode": "trace",
"shared": false
}
FieldTypeRequiredDescription
namestringYesName of the saved search
pipelinearrayYesJSON pipeline for trace queries
modestringYesQuery mode: span or trace
sharedbooleanNoShare with organization (default: false)
PUT /traces/searches/{id}
DELETE /traces/searches/{id}

Recent Searches

Access recently executed trace searches (retained for 7 days).

GET /traces/recent-searches

Query Parameters

ParameterTypeRequiredDescription
query_sourcestringNoFilter by source: manual or nlp

Error Handling

Error Response Format

{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message"
}
}

Common Errors

HTTP StatusErrorDescription
400region query parameter is requiredMissing required region parameter
401Authorization token is expiredAccess token has expired
403ForbiddenInsufficient permissions
404Not FoundResource not found
500ERR_S3_CONFIG_MISSINGOTLP configuration not found for org

Debugging Common Scenarios

No Data Returned

If your query returns an empty result array, check the following:

  1. Field names: Verify the field names are correct. Use Get Trace Tags to discover available fields.
  2. Time range: Ensure your start and end timestamps cover a period where traces exist. Timestamps are in Unix seconds.
  3. Data retention: Check if the queried time range is within your organization’s data retention period.
  4. Pipeline syntax: Make sure your JSON pipeline is correctly formatted. Each operator takes an array with exactly 2 elements: ["field", "value"].
  5. Mode: Verify you are using the correct mode (span vs trace) for your use case.

Authorization Issues

If you receive authentication errors:

  1. Token validity: Verify your access token is valid and not expired.
  2. Header format: The header must be X-LAST9-API-TOKEN: Bearer <TOKEN>.
  3. Organization slug: Ensure the {org-slug} in the URL matches your organization.

API Endpoints Summary

MethodEndpointDescription
POST/cat/api/traces/v2/query_range/jsonQuery traces with pipeline
POST/cat/api/traces/v2/search/jsonSearch traces with span sets
GET/cat/api/traces/{traceID}Get trace by ID
POST/cat/api/traces/v2/heatmap/jsonGet trace duration heatmap
POST/cat/api/traces/v2/series/jsonGet available tags
POST/cat/api/traces/v2/label/json/{tagName}/valuesGet tag values
GET/traces/searchesList saved searches
POST/traces/searchesCreate saved search
PUT/traces/searches/{id}Update saved search
DELETE/traces/searches/{id}Delete saved search
GET/traces/recent-searchesList recent searches

Troubleshooting

Please get in touch with us on Discord or Email if you have any questions.