Create multiple spans (up to 1000) in a single request and return the created spans.
Prefer this over repeated POST /v5/spans calls when ingesting many spans at
once; use PUT /v5/spans/batch instead when a span with the same id may
already exist, since this endpoint inserts new spans rather than overwriting.
A batch larger than 1000 spans is rejected with a validation error. Each item
follows the same id-generation and per-account dual-write rules as the
single-span create, including that end_timestamp must not precede
start_timestamp, which rejects the request with a 422. When the tracing
service is the primary store, its 400, 413 and 422 rejections keep that status
and detail, as does a 403 when the request carried its own API key, and every
other failure returns a 503 with a Retry-After header. A batch that forms a cycle,
or a span whose parent belongs to another trace, is rejected with 409 before either
store is written. A parent outside the batch is looked up in Postgres, so that part
of the check ends once the account’s spans stop being written there. Postgres
rejects an id that already exists, while the tracing service treats the write
as an upsert. Which writes the tracing service rejects depends in part on its
storage engine: on Postgres deployments a NUL byte or invalid UTF-8 inside
trace_id, id, parent_id or group_id fails the whole batch with a 400
naming the field, because replacing the byte would change the identity the
response echoes; a NUL byte or invalid UTF-8 in any other field is replaced with
U+FFFD and the span is persisted. ClickHouse deployments store the bytes verbatim.
Credential redaction: values in the free-form input, output, metadata,
and expected objects, and in name, that are credential-shaped (bearer/JWT,
API keys, connection-string passwords) or under a credential-named key are replaced
with [REDACTED:credential] before the span is persisted, so the stored and
returned span reflects the redacted value (EY 12.3).
Create spans in a batch
import os
from datetime import datetime
from scale_gp_beta import SGPClient
client = SGPClient(
api_key=os.environ.get("SGP_API_KEY"), # This is the default and can be omitted
)
api_list_span = client.spans.batch(
items=[{
"name": "name",
"start_timestamp": datetime.fromisoformat("2019-12-27T18:11:19.117"),
"trace_id": "trace_id",
}],
)
print(api_list_span.items){
"items": [
{
"id": "id",
"account_id": "account_id",
"name": "name",
"start_timestamp": "2019-12-27T18:11:19.117Z",
"trace_id": "trace_id",
"application_interaction_id": "application_interaction_id",
"application_variant_id": "application_variant_id",
"created_by": {
"id": "id",
"type": "user",
"object": "identity"
},
"end_timestamp": "2019-12-27T18:11:19.117Z",
"expected": {
"foo": "bar"
},
"group_id": "group_id",
"input": {
"foo": "bar"
},
"input_tokens": 0,
"metadata": {
"foo": "bar"
},
"object": "span",
"obs_span_id": "obs_span_id",
"obs_trace_id": "obs_trace_id",
"output": {
"foo": "bar"
},
"output_tokens": 0,
"parent_id": "parent_id",
"status": "SUCCESS",
"type": "TEXT_INPUT"
}
],
"object": "list"
}Returns Examples
{
"items": [
{
"id": "id",
"account_id": "account_id",
"name": "name",
"start_timestamp": "2019-12-27T18:11:19.117Z",
"trace_id": "trace_id",
"application_interaction_id": "application_interaction_id",
"application_variant_id": "application_variant_id",
"created_by": {
"id": "id",
"type": "user",
"object": "identity"
},
"end_timestamp": "2019-12-27T18:11:19.117Z",
"expected": {
"foo": "bar"
},
"group_id": "group_id",
"input": {
"foo": "bar"
},
"input_tokens": 0,
"metadata": {
"foo": "bar"
},
"object": "span",
"obs_span_id": "obs_span_id",
"obs_trace_id": "obs_trace_id",
"output": {
"foo": "bar"
},
"output_tokens": 0,
"parent_id": "parent_id",
"status": "SUCCESS",
"type": "TEXT_INPUT"
}
],
"object": "list"
}