Amazon S3 is a scalable object storage service. OpenRouter can send traces to any S3-compatible storage, including AWS S3, Cloudflare R2, MinIO, and other compatible services.
Make an API request through OpenRouter and check your S3 bucket for the trace file. Each trace is saved as a separate JSON file with the format {traceId}-{timestamp}.json.
Customize how traces are organized in your bucket:
openrouter-traces/{date} - Default, organizes by date (e.g., openrouter-traces/2024-01-15/abc123-1705312800.json)
traces/{year}/{month}/{day} - Hierarchical date structure
{apiKeyName}/{date} - Organize by API key name, then date
production/llm-traces/{date} - Custom prefix for environment separation
For time-based batching (e.g., hourly or daily aggregated files), consider using AWS Kinesis Firehose instead, which buffers records and writes batched files to S3.
Custom metadata from the trace field is included in the JSON trace file stored in your S3 bucket. The metadata is available in the metadata field of each observation within the trace.
Each trace file is a JSON object. Custom metadata keys from trace are stored in the metadata field and can be queried using tools like Amazon Athena, Presto, or any JSON-aware query engine:
-- Example Athena query on S3 trace filesSELECT json_extract_scalar(metadata, '$.document_type') as doc_type, json_extract_scalar(metadata, '$.batch_id') as batch_idFROM openrouter_tracesWHERE json_extract_scalar(metadata, '$.document_type') = 'contract';
For a single-trace file, cache-write details live under trace.observations[].promptTokensDetails. With the Cost metadata opt-in enabled, the generation quantities also appear under trace.metadata.openrouter_generation and the generation observation’s metadata.openrouter_generation.For example, the generation metadata may contain:
Batch files use traces[] instead of trace. Read each generation once. These representations repeat the same generation quantities; do not add them together. Null or omitted values are unavailable, while an explicit zero is a reported or observed zero. See Token and cost fields for estimation, TTL availability, and provider billing caveats.
The value can also be an array of usage reports or null, and its keys are the provider’s own. Query it with a JSON-aware engine rather than a fixed column list, for example json_extract(metadata, '$.openrouter_generation.upstream_raw_response_usage') in Athena. When it is null, check upstream_raw_response_usage_suppression_reason to distinguish suppression from unavailable usage.
When Privacy Mode is enabled for this destination, prompt and completion content is excluded from traces. All other trace data (token usage, costs, timing, model information, and custom metadata) is still sent normally. Raw provider usage is replaced with null and reported as privacy_mode, because a provider’s usage object can contain arbitrary future fields. See Privacy Mode for details.
Was this page helpful?
Assistant
Responses are generated using AI and may contain mistakes.