Trace Summary
observability.trace_summary
Overview
You send up to 100000 already-normalized spans and an optional attribute allowlist of at most 20 keys. The answer is duration, a critical-path approximation, service and operation counts, error counts, roots, orphans and the slowest spans. Only allowlisted attribute values are returned; everything else is dropped. This does not fetch traces or claim a causal root cause. A successful call costs 2 execution credits.
A bounded span batch needs a published summary that cannot leak unaudited attributes.
Reliability
OBS_TRACE_SUMMARY_INVALID — trigger: duplicate spanId; retryable: no; next: send unique ids. OBS_TRACE_SUMMARY_LIMIT_EXCEEDED — trigger: more than 100000 spans or more than 20 allowlist keys; retryable: no; next: split the batch.
Context footprint
Only allowlisted attribute values are returned. A successful call costs 2 execution credits.
When to use it
When a caller already holds normalized spans and needs counts, roots and a critical-path approximation.
When the traces still live in a backend, or when a causal root-cause narrative is required.
Powered by Squillify's own span-graph walk. No telemetry backend is involved.
Scope
Non-goals
- Does not fetch traces
- Does not claim a causal root cause
- Does not implement full OpenTelemetry semantics
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
What this means
This skill may receive sensitive content and may return submitted, transformed, extracted, or reformatted content.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response may contain submitted or transformed content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| spans | array | Yes | Normalized spans, 0 through 100001 closed objects; runtime accepts at most 100000. |
| attributeAllowlist | array | No | Allowlist of 0 through 21 attribute keys; runtime accepts at most 20. Omit it to return no attribute values. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| spanCount | integer | Yes | How many spans were accepted. |
| rootCount | integer | Yes | How many spans have no parentSpanId. |
| orphanCount | integer | Yes | How many spans name a parent that is not in the batch. |
| errorCount | integer | Yes | How many spans have status ERROR. |
| durationNanos | integer | Yes | max(endNanos) minus min(startNanos) across the batch, or 0 when empty. |
| criticalPathNanos | integer | Yes | Longest root-to-leaf duration sum used as a critical-path approximation. |
| criticalPathSpanId | string | Yes | Span id at the start of the longest path, or empty when the batch is empty. |
| roots | array | Yes | Root span ids sorted lexicographically, 0 through 100000 strings. |
| orphans | array | Yes | Orphan span ids sorted lexicographically, 0 through 100000 strings. |
| services | object | Yes | Name to non-negative span count sorted by count then name — unconstrained RFC 8259 JSON items are not used. |
| operations | object | Yes | Name to non-negative span count sorted by count then name — unconstrained RFC 8259 JSON items are not used. |
| topSlowSpans | array | Yes | Up to 10 slowest spans as closed {spanId, name, durationNanos, status, attributes?} objects. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"observability.trace_summary","input":{"spans":[{"spanId":"root","name":"GET /orders","startNanos":0,"endNanos":40}]}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("observability.trace_summary", {"attributeAllowlist":["http.status_code"],"spans":[{"traceId":"t1","spanId":"root","name":"GET /orders","kind":"SERVER","startNanos":0,"endNanos":40,"status":"OK","service":"api","attributes":{"http.status_code":"200","secret":"drop-me"}},{"traceId":"t1","spanId":"child","parentSpanId":"root","name":"SELECT orders","kind":"SERVER","startNanos":5,"endNanos":25,"status":"ERROR","service":"api","attributes":{"http.status_code":"500","secret":"drop-me"}}]});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| OBS_TRACE_SUMMARY_INVALID | 400 | No | The request payload failed this skill's input validation. |
| OBS_TRACE_SUMMARY_LIMIT_EXCEEDED | 429 | No | A size, quota, rate, or time limit was exceeded. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Does not fetch traces
- Does not claim a causal root cause
- Does not implement full OpenTelemetry semantics
- Live trace query
- Root-cause claims
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "observability.trace_summary",
"input": {
"attributeAllowlist": [
"http.status_code"
],
"spans": [
{
"traceId": "t1",
"spanId": "root",
"name": "GET /orders",
"kind": "SERVER",
"startNanos": 0,
"endNanos": 40,
"status": "OK",
"service": "api",
"attributes": {
"http.status_code": "200",
"secret": "drop-me"
}
},
{
"traceId": "t1",
"spanId": "child",
"parentSpanId": "root",
"name": "SELECT orders",
"kind": "SERVER",
"startNanos": 5,
"endNanos": 25,
"status": "ERROR",
"service": "api",
"attributes": {
"http.status_code": "500",
"secret": "drop-me"
}
}
]
}
}Examples
A root and an error child report one orphan-free tree
{
"attributeAllowlist": [
"http.status_code"
],
"spans": [
{
"traceId": "t1",
"spanId": "root",
"name": "GET /orders",
"kind": "SERVER",
"startNanos": 0,
"endNanos": 40,
"status": "OK",
"service": "api",
"attributes": {
"http.status_code": "200",
"secret": "drop-me"
}
},
{
"traceId": "t1",
"spanId": "child",
"parentSpanId": "root",
"name": "SELECT orders",
"kind": "SERVER",
"startNanos": 5,
"endNanos": 25,
"status": "ERROR",
"service": "api",
"attributes": {
"http.status_code": "500",
"secret": "drop-me"
}
}
]
}{
"rootCount": 1,
"services": {
"api": 2
},
"criticalPathSpanId": "root",
"criticalPathNanos": 60,
"orphans": [],
"spanCount": 2,
"topSlowSpans": [
{
"spanId": "root",
"name": "GET /orders",
"durationNanos": 40,
"status": "OK",
"attributes": {
"http.status_code": "200"
}
},
{
"spanId": "child",
"name": "SELECT orders",
"durationNanos": 20,
"status": "ERROR",
"attributes": {
"http.status_code": "500"
}
}
],
"errorCount": 1,
"operations": {
"GET /orders": 1,
"SELECT orders": 1
},
"orphanCount": 0,
"roots": [
"root"
],
"durationNanos": 40
}An empty span list is a successful zero summary
{
"spans": []
}{
"rootCount": 0,
"services": {},
"criticalPathSpanId": "",
"criticalPathNanos": 0,
"orphans": [],
"spanCount": 0,
"topSlowSpans": [],
"errorCount": 0,
"operations": {},
"orphanCount": 0,
"roots": [],
"durationNanos": 0
}Recommended use cases
- Summarize an already-exported trace batch
- Redact span attributes down to an allowlist
Avoid for
- Live trace query
- Root-cause claims
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.