## Create spans in a batch

`spans.batch(SpanBatchParams**kwargs)  -> APIListSpan`

**post** `/v5/spans/batch`

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

### Parameters

- `items: Iterable[SpanCreateParam]`

  - `name: str`

  - `start_timestamp: datetime`

    When the span started. With trace_id and id it forms the span's storage identity, so a span re-sent with a start_timestamp on another UTC day is stored as a second row that the store never collapses. Get span and trace detail return the newest version. Search returns the newest version whose start_timestamp falls in the queried window. Export, metrics and facets count both rows until the trace is deleted and re-sent.

  - `trace_id: str`

    id for grouping traces together, uuid is recommended

  - `id: Optional[str]`

    The id of the span, at most 256 bytes. A value longer than 256 characters is refused here with a 422 before it is forwarded; a value within that count whose UTF-8 form exceeds 256 bytes is refused with a 400 naming the field once the tracing service is the account's primary store, and accepted for accounts still written primarily to the legacy trace store.

  - `application_interaction_id: Optional[str]`

    The optional application interaction ID this span belongs to

  - `application_variant_id: Optional[str]`

    The optional application variant ID this span belongs to

  - `end_timestamp: Optional[datetime]`

  - `expected: Optional[Dict[str, object]]`

  - `group_id: Optional[str]`

    Reference to a group_id, at most 256 bytes. A value longer than 256 characters is refused here with a 422 before it is forwarded; a value within that count whose UTF-8 form exceeds 256 bytes is refused with a 400 naming the field once the tracing service is the account's primary store, and accepted for accounts still written primarily to the legacy trace store.

  - `input: Optional[Dict[str, object]]`

  - `metadata: Optional[Dict[str, object]]`

  - `obs_span_id: Optional[str]`

    W3C span id (16 lowercase hex chars) of the observability span this span executed in. Requires obs_trace_id.

  - `obs_trace_id: Optional[str]`

    W3C trace id (32 lowercase hex chars) of the observability trace this span executed in, for correlating a business span with the infrastructure work it caused. Stored only by the sgp-traces service, so accounts still served by the legacy store accept the field and read it back as null.

  - `output: Optional[Dict[str, object]]`

  - `parent_id: Optional[str]`

    Reference to a parent span_id

  - `status: Optional[SpanStatus]`

    - `"SUCCESS"`

    - `"ERROR"`

    - `"CANCELED"`

  - `type: Optional[SpanType]`

    - `"TEXT_INPUT"`

    - `"TEXT_OUTPUT"`

    - `"COMPLETION_INPUT"`

    - `"COMPLETION"`

    - `"KB_RETRIEVAL"`

    - `"KB_INPUT"`

    - `"RERANKING"`

    - `"EXTERNAL_ENDPOINT"`

    - `"PROMPT_ENGINEERING"`

    - `"DOCUMENT_INPUT"`

    - `"MAP_REDUCE"`

    - `"DOCUMENT_SEARCH"`

    - `"DOCUMENT_PROMPT"`

    - `"CUSTOM"`

    - `"CODE_EXECUTION"`

    - `"DATA_MANIPULATION"`

    - `"EVALUATION"`

    - `"FILE_RETRIEVAL"`

    - `"KB_ADD_CHUNK"`

    - `"KB_MANAGEMENT"`

    - `"GUARDRAIL"`

    - `"OUTPUT_GUARDRAIL"`

    - `"TRACER"`

    - `"AGENT_TRACER"`

    - `"AGENT_WORKFLOW"`

    - `"STANDALONE"`

### Returns

- `class APIListSpan: …`

  - `items: List[Span]`

    - `id: str`

    - `account_id: str`

    - `name: str`

    - `start_timestamp: datetime`

    - `trace_id: str`

      id for grouping traces together, uuid is recommended

    - `application_interaction_id: Optional[str]`

      The interaction ID this span belongs to

    - `application_variant_id: Optional[str]`

      The id of the application variant this span belongs to

    - `created_by: Optional[Identity]`

      The identity that created the entity.

      - `id: str`

      - `type: Literal["user", "service_account"]`

        - `"user"`

        - `"service_account"`

      - `object: Optional[Literal["identity"]]`

        - `"identity"`

    - `end_timestamp: Optional[datetime]`

    - `expected: Optional[Dict[str, object]]`

    - `group_id: Optional[str]`

      Reference to a group_id

    - `input: Optional[Dict[str, object]]`

    - `input_tokens: Optional[int]`

      Prompt tokens the producer reported for this span, absent when it reported none. Same quantity the input_tokens sort orders by.

    - `metadata: Optional[Dict[str, object]]`

    - `object: Optional[Literal["span"]]`

      - `"span"`

    - `obs_span_id: Optional[str]`

      W3C span id of the observability span this span executed in.

    - `obs_trace_id: Optional[str]`

      W3C trace id of the observability trace this span executed in. Null for spans written without the edge, and for accounts still served by the legacy trace store.

    - `output: Optional[Dict[str, object]]`

    - `output_tokens: Optional[int]`

      Completion tokens the producer reported for this span, absent when it reported none. Same quantity the output_tokens sort orders by.

    - `parent_id: Optional[str]`

      Reference to a parent span_id

    - `status: Optional[SpanStatus]`

      - `"SUCCESS"`

      - `"ERROR"`

      - `"CANCELED"`

    - `type: Optional[SpanType]`

      - `"TEXT_INPUT"`

      - `"TEXT_OUTPUT"`

      - `"COMPLETION_INPUT"`

      - `"COMPLETION"`

      - `"KB_RETRIEVAL"`

      - `"KB_INPUT"`

      - `"RERANKING"`

      - `"EXTERNAL_ENDPOINT"`

      - `"PROMPT_ENGINEERING"`

      - `"DOCUMENT_INPUT"`

      - `"MAP_REDUCE"`

      - `"DOCUMENT_SEARCH"`

      - `"DOCUMENT_PROMPT"`

      - `"CUSTOM"`

      - `"CODE_EXECUTION"`

      - `"DATA_MANIPULATION"`

      - `"EVALUATION"`

      - `"FILE_RETRIEVAL"`

      - `"KB_ADD_CHUNK"`

      - `"KB_MANAGEMENT"`

      - `"GUARDRAIL"`

      - `"OUTPUT_GUARDRAIL"`

      - `"TRACER"`

      - `"AGENT_TRACER"`

      - `"AGENT_WORKFLOW"`

      - `"STANDALONE"`

  - `object: Optional[Literal["list"]]`

    - `"list"`

### Example

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

#### Response

```json
{
  "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"
}
```
