---
title: "Create spans in bulk"
method: POST
path: "/api/request-logs/bulk/"
tags: ["Spans"]
---

# Create spans in bulk

`POST /api/request-logs/bulk/`

## Request

- Base URL: `https://api.respan.ai`
- URL: `https://api.respan.ai/api/request-logs/bulk/`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Accepts up to 500 spans per request. Each item in `logs` uses the fields in [Create a span](/docs/apis/spans/create-span). Rows are processed independently. A `201 Created` response means at least one row was accepted, so check `error_count` and `errors` for partial failures. `success_count` counts rows that passed synchronous validation and were accepted for ingestion.

Rate limit: 30 requests per minute per organization for API-key calls, shared across the organization's keys. For JWT calls, the limit is per user. Metadata keys beginning with `_` are reserved for platform use and omitted from span and trace read responses.

## Request body

- object
  - `logs` SpanCreateRequest[], required: Non-empty array of span payloads. Each object uses the same schema as `POST /api/request-logs/`.
    - `model` string, required: Model used for the span.
    - `prompt_messages` object[]: Chat input messages for the request log.
    - `completion_message` object: Assistant message returned by the model.
    - `prompt_tokens` integer: Prompt/input tokens for the request. For Anthropic logs this corresponds to `input_tokens` before cache-token normalization.
    - `completion_tokens` integer: Completion/output tokens for the request. For Anthropic logs this corresponds to `output_tokens`.
    - `usage` object: Provider usage object. Cache token fields such as `cache_creation_input_tokens` and `cache_read_input_tokens` are accepted and normalized into Respan cache-token counters.
      - `prompt_tokens` integer
      - `completion_tokens` integer
      - `total_tokens` integer
      - `input_tokens` integer: Anthropic input token count.
      - `output_tokens` integer: Anthropic output token count.
      - `cache_creation_input_tokens` integer: Anthropic cache-creation input tokens. Normalized to `prompt_cache_creation_tokens`.
      - `cache_read_input_tokens` integer: Anthropic cache-read input tokens. Normalized to `prompt_cache_hit_tokens`.
    - `temperature` number: Sampling temperature (0-2). Higher = more random.
    - `top_p` number: Nucleus sampling parameter.
    - `max_tokens` integer: Maximum tokens to generate.
    - `generation_time` number: Accepted alias for total generation latency in seconds. Stored as `latency` in responses and query results.
    - `ttft` number: Accepted alias for time to first token in seconds. Stored as `time_to_first_token` in responses and query results.
    - `customer_params` object: Extended customer information. `customer_identifier` inside this object is promoted to the log customer identifier.
      - `customer_identifier` string
      - `email` string
      - `name` string
    - `metadata` object: Arbitrary customer metadata. Keys beginning with `_` are reserved and omitted from customer-facing read responses.
    - `environment` 'prod' | 'test': Stored environment for the log. This is derived from the API key environment; body-supplied values do not override a prod/test key.
    - `stream` boolean: Whether the response was streamed.
    - `status_code` integer: HTTP status code of the request.
    - `tools` object[]: Tools available to the model (OpenAI function calling format).
    - `tool_calls` object[]: Tool calls returned by the model.
    - `timestamp` string, date-time: ISO 8601 timestamp when the request completed.
    - `trace_unique_id` string: Trace ID to link spans into a trace tree.
    - `span_name` string: Name of this span within the workflow.
    - `span_parent_id` string: Parent span ID. Builds the trace hierarchy.
    - `span_workflow_name` string: Name of the parent workflow.
    - `custom_identifier` string: Indexed custom identifier for fast querying.
    - `thread_identifier` string: Conversation thread ID for multi-turn conversations.
    - `group_identifier` string: Groups related spans together.
    - `latency` number: Total request latency in seconds. `generation_time` is also accepted and normalizes to this field.
    - `time_to_first_token` number: Time to first token in seconds. `ttft` is also accepted and normalizes to this field.
    - `log_type` 'chat' | 'completion' | 'response' | 'embedding' | 'speech' | 'transcription' | 'workflow' | 'agent' | 'task' | 'tool' | 'guardrail' | 'reranker' | 'other': Type of span. Determines how `input` and `output` are parsed.
    - `input` union: Preferred universal input field. For chat spans, send an array of message objects or a JSON string. For non-chat spans, send any string/object/array structure that represents the span input.
      - string
      - object
      - object[]
    - `output` union: Preferred universal output field. For chat spans, send an assistant message object or a JSON string. For non-chat spans, send any string/object/array structure that represents the span output.
      - string
      - object
      - object[]
    - `messages` object[]: Legacy chat input field. Equivalent to `prompt_messages`; prefer `input` for new integrations.
    - `cost` number: Cost in USD. Auto-calculated from model pricing if omitted.
    - `tokens_per_second` number: Generation speed in tokens per second.
    - `properties` object: Typed metadata that preserves native JSON types.
    - `variables` object: Variables used for prompt templates.
    - `customer_identifier` string: Identifier for the end user who made this request.
    - `tool_choice` union: Controls tool selection. `"none"`, `"auto"`, or a specific tool object.
      - string
      - object
    - `response_format` object: Response format configuration (e.g. JSON mode or structured output).
    - `frequency_penalty` number: Penalizes repeated tokens (-2 to 2).
    - `presence_penalty` number: Penalizes tokens already present (-2 to 2).
    - `stop` union: Stop sequence or sequences where generation halts.
      - string
      - string[]
    - `error_message` string: Error message if the request failed.
    - `warnings` union: Warnings from the request.
      - string
      - object
    - `status` 'success' | 'error': Request status. `error` is stored as `failed`.
    - `prompt_id` string: ID of the Respan prompt template used.
    - `prompt_name` string: Name of the prompt template.
    - `is_custom_prompt` boolean: Not read at the top level. Respan reads `is_custom_prompt` only inside a `prompt` object, as in `{"prompt": {"prompt_id": "your-id", "is_custom_prompt": true}}`. Set it there for a prompt you manage outside Respan. Otherwise Respan looks up `prompt.prompt_id` among your saved prompts and rejects the span if none matches. A top-level `prompt_id` is logged as sent and isn't looked up.
    - `start_time` string, date-time: ISO 8601 timestamp when the request started.
    - `full_request` object: Full raw request object for reference.
    - `full_response` object: Full raw response object from the provider.
    - `prompt_unit_price` number: Custom price per 1M prompt tokens (for self-hosted/fine-tuned models).
    - `completion_unit_price` number: Custom price per 1M completion tokens (for self-hosted/fine-tuned models).
    - `respan_params` object: Preferred namespace for Respan-specific controls such as customer tagging, metadata, prompt loading, cache settings, and logging flags.
    - `keywordsai_params` object: Legacy alias for `respan_params`. Still accepted and merged into `respan_params`.
    - `positive_feedback` boolean: User feedback. `true` = positive, `false` = negative.
    - `error_code` string: Normalized application or provider error code.

## Response `201`

At least one row was accepted. This status is also used for partial success; inspect the response counts and indexed errors.

- BulkOperationResponse: Canonical result envelope for a bulk operation.
  - `success_count` integer, required: Number of items successfully processed.
  - `error_count` integer, required: Number of items that failed.
  - `errors` BulkItemError[], required: Item-level failures, keyed by zero-based input index.
    - `index` integer, required: Zero-based index of the failed item in the submitted array.
    - `error` string, required: Error message for the failed item.

## Other responses

- `400`: Every row failed, the `logs` envelope was missing or malformed, the list was empty, or the organization is blocked.
- `403`: The API key is missing, invalid or expired, or it can't access this organization.
- `422`: The batch contains more than 500 rows.
- `429`: Rate limit exceeded.

## Changes

- **2026-10-21** `c30bcb383ee8`: 3 breaking, 61 info
  - added the new required request property `logs/items/model`
  - request body became required
  - the `logs` request property's minItems was increased to `1`
  - api operation id `spans_bulkCreateSpans` removed and replaced with `bulkCreateSpans`
  - …60 more
- **2026-10-02** `b830b79cfd52`: 1 breaking, 2 info
  - the response's body type changed from no type to `object` for status `403`
  - removed the non-success response with the status `401`
  - added the required property `detail` to the response with the `403` status
- **2026-09-17** `6fa8242da8c2`: 1 warning, 1 info
  - deleted the `header` request parameter `Authorization`
  - the endpoint scheme security `RespanApiKey` was added to the API
- **2026-09-12** `22b868ef3f22`: 1 info
  - api operation id `bulk-create-spans` removed and replaced with `spans_bulkCreateSpans`
- **2026-08-13** `4e064cf81dae`: 1 breaking, 7 info
  - removed the success response with the status `200`
  - added optional request body
  - added the non-success response with the status `400`
  - added the non-success response with the status `401`
  - …4 more

[Operation history](https://skmtc.dev/keywordsai/apis/respan-api/changes/api/request-logs/bulk/post.md)

---

[API](https://skmtc.dev/keywordsai/apis/respan-api.md) - [All operations](https://skmtc.dev/keywordsai/apis/respan-api/llms.txt) - [OpenAPI document](https://skmtc.dev/keywordsai/apis/respan-api/revisions/900841387635?raw)
