To start querying request logs, install and configure the TrueFoundry SDK and CLI.
Follow the CLI Setup Guide for installation instructions and authentication steps.Once setup is complete, you can use the SDK to query tracing data programmatically.
Each request to the LLM Gateway generates a trace—a timeline of everything that happened, from the incoming request to guardrails to the model call and any external APIs.
Let’s pull the latest Gateway traces and see real data quickly.Fetch the latest LLM Gateway request logs:
You can get the tracing_project_fqn from the Fetch via API button on the Request Logs page
Copy
Ask AI
from truefoundry import client# Fetch LLM Gateway request logsspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-01-21T00:00:00.000Z", application_names=["tfy-llm-gateway"],)for span in spans: print(span.span_name, span.span_attributes.get('tfy.span_type'))
To start querying request logs, you need to authenticate with your TrueFoundry API key. You can use either a Personal Access Token (PAT) or Virtual Account Token (VAT).
Get your API key
To generate an API key:
Personal Access Token (PAT): Go to Access → Personal Access Tokens in your TrueFoundry dashboard
Virtual Account Token (VAT): Go to Access → Virtual Account Tokens (requires admin permissions)
Each request to the LLM Gateway generates a trace—a timeline of everything that happened, from the incoming request to guardrails to the model call and any external APIs.
Let’s pull the latest Gateway traces and see real data quickly.Fetch the latest LLM Gateway request logs:
You can get the tracing_project_fqn from the Fetch via API button on the Request Logs page
Copy
Ask AI
import requestspage_token = Nonedone = Falsewhile not done: # Make API request response = requests.post( "https://{control_plane_url}/api/svc/v1/spans/query", headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" }, json={ "startTime": "2025-10-08T20:16:54", "tracingProjectFqn": "{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", "applicationNames": ["tfy-llm-gateway"], "pageToken": page_token } ) response.raise_for_status() data = response.json() for span in data['data']: print(span['spanName'], span['spanAttributes'].get('tfy.span_type', '')) page_token = data['pagination'].get("nextPageToken") done = page_token is Noneprint("Fetch spans completed!")
Now that you’ve run a basic query, inspect one request end-to-end. The examples below fetch all spans for a specific trace_id, so you can see the full hierarchy (root request, guardrail processing, model span, and outbound HTTP calls).
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirection# Fetch all spans for a specific trace ID with guardrail processingtrace_id = "019a047ee43577009b6bb5b6ab9477d2"spans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-21T00:00:00.000Z", end_time="2025-10-21T23:59:59.999Z", trace_ids=["019a047ee43577009b6bb5b6ab9477d2"], application_names=["tfy-llm-gateway"], limit=200, sort_direction=SortDirection.DESC)for span in spans: print(span)
The following trace contains 5 spans that form a hierarchical relationship, demonstrating a request flow with PII redaction guardrail processing:
Chat completion request with guardrail processing span hierarchy
The following example demonstrates a complete trace with 5 spans that form a hierarchical relationship. Each span represents a different phase of the request processing, from the initial chat completion request through guardrail processing to the final model inference and network calls.
ChatCompletion Span (Root Span)
The ChatCompletion span with ID bddb6503c0eeb940 serves as the root span with no parent span ID (empty parent_span_id).
This span represents the complete chat completion request lifecycle from the client’s perspective, capturing the total time from when the request enters the gateway until the response is sent back to the client.
With a duration of 7.09 seconds, it provides the overall performance measurement for the entire request flow.
The span includes the tfy.triggered_guardrail_fqns attribute showing which guardrails were triggered during processing.
Hide View ChatCompletion Span Details
Copy
Ask AI
TraceSpan( span_id='bddb6503c0eeb940', trace_id='019a047ee43577009b6bb5b6ab9477d2', parent_span_id='', service_name='tfy-llm-gateway', span_name='ChatCompletion: openai-main/gpt-5', timestamp='2025-10-21T02:00:16.181Z', duration_ns=7087251623.0, status_code='Unset', span_attributes={ 'tfy.model.fqn': 'truefoundry:openai:openai-main:model:gpt-5', 'tfy.model.request_type': 'ChatCompletion', 'tfy.error_message': '', 'tfy.model.name': 'openai-main/gpt-5', 'tfy.model.id': 'cme6zartb0v0701pjeqk9fulg', 'tfy.triggered_guardrail_fqns': ['truefoundry:guardrail-config-group:pii-guardrails:guardrail-config:pii-redaction'], 'tfy.model.metric.inter_token_latency_in_ms': 0, 'tfy.model.metric.time_to_first_token_in_ms': 7022.75, 'tfy.model.metric.latency_in_ms': 6600.23, 'tfy.model.metric.input_tokens': 12, 'tfy.model.metric.cost_in_usd': 0.00481501, 'tfy.model.metric.output_tokens': 480, 'tfy.input': '{"model":"openai-main/gpt-5","messages":[{"role":"user","content":"I am sateesh. Hi"}],"stream":true}', 'tfy.output': '{"id":"chatcmpl-CSvxYlQKenRQWspGHQaCLRcz1MbZU","usage":{"prompt_tokens":12,"completion_tokens":480,"cache_read_tokens":0,"cache_write_tokens":0,"reasoning_tokens":448,"total_tokens":492},"object":"chat.completion","model":"gpt-5-2025-08-07","created":1761012016,"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"role":"assistant","content":"Hi! Nice to meet you. What would you like me to call you, and how can I help today?","refusal":null}}]}', 'tfy.span_type': 'ChatCompletion' }, events=[], created_by_subject=Subject( subject_id='sateesh@truefoundry.com', subject_type=<SubjectType.USER: 'user'>, subject_slug='sateesh@truefoundry.com', subject_display_name=None ))
Guardrail Span
The Guardrail span with ID d46e8d5202edc22c has a parent span “ChatCompletion Span (Root Span)” with ID bddb6503c0eeb940, representing the PII redaction guardrail processing.
This span shows the guardrail configuration used.
The Guardrail Network Call span with ID fb07005b3c28a98b has a parent span “Guardrail Span” with ID d46e8d5202edc22c, representing the actual HTTP communication with the external guardrail service (AWS Bedrock). This span captures the network latency and external guardrail service processing time. With a duration of 0.48 seconds, it shows the time spent on the actual guardrail API call.
The Model span with ID de09be32ba8e0c37 has a parent span “ChatCompletion Span (Root Span)” with ID bddb6503c0eeb940, making it a sibling to the Guardrail span.
This span contains all the detailed model metrics and represents the LLM model inference processing within the gateway.
Notice how the input content has been redacted from I am sateesh. Hi to I am {NAME}. Hi, demonstrating the PII redaction working.
Hide View Model Span Details
Copy
Ask AI
TraceSpan( span_id='de09be32ba8e0c37', trace_id='019a047ee43577009b6bb5b6ab9477d2', parent_span_id='bddb6503c0eeb940', service_name='tfy-llm-gateway', span_name='Model: openai-main/gpt-5', timestamp='2025-10-21T02:00:16.667Z', duration_ns=6600714193.0, status_code='Ok', span_attributes={ 'tfy.model.fqn': 'truefoundry:openai:openai-main:model:gpt-5', 'tfy.model.id': 'cme6zartb0v0701pjeqk9fulg', 'tfy.model.name': 'openai-main/gpt-5', 'tfy.model.request_url': 'https://api.openai.com/v1/chat/completions', 'tfy.model.request_type': 'ChatCompletion', 'tfy.error_message': '', 'tfy.model.metric.cost_in_usd': 0.00481501, 'tfy.model.metric.inter_token_latency_in_ms': 0, 'tfy.model.metric.time_to_first_token_in_ms': 7022.75, 'tfy.model.metric.input_tokens': 12, 'tfy.model.metric.latency_in_ms': 6600.23, 'tfy.model.metric.output_tokens': 480, 'tfy.model.streaming': True, 'tfy.input': '{"model":"openai-main/gpt-5","messages":[{"role":"user","content":"I am {NAME}. Hi"}],"stream":true}', 'tfy.output': '{"id":"chatcmpl-CSvxYlQKenRQWspGHQaCLRcz1MbZU","usage":{"prompt_tokens":12,"completion_tokens":480,"cache_read_tokens":0,"cache_write_tokens":0,"reasoning_tokens":448,"total_tokens":492},"object":"chat.completion","model":"gpt-5-2025-08-07","created":1761012016,"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"role":"assistant","content":"Hi! Nice to meet you. What would you like me to call you, and how can I help today?","refusal":null}}]}', 'tfy.span_type': 'Model' }, created_by_subject=Subject( subject_id='sateesh@truefoundry.com', subject_type=<SubjectType.USER: 'user'>, subject_slug='sateesh@truefoundry.com', subject_display_name=None ))
Model Network Call Span
The Model Network Call span with ID 95794dcfbaad832a has a parent span “Model Span” with ID de09be32ba8e0c37, representing the actual HTTP communication with the external provider (OpenAI). This span captures pure network latency and external provider processing time. With a duration of 6.60 seconds, it shows the time spent on the actual API call to the external service.
While fetching all Gateway request logs is useful for general monitoring,
you’ll often want to filter logs based on specific criteria such as user identity, model names, etc.
You can achieve this using the filters parameter in the query_spans method.The API supports the following common filter types:
Span fields filtering: Filter logs by span fields such as spanName, traceId, spanId, etc. See the Query Spans documentation to understand the supported options for spanFieldName and operator.
Span attributes filtering: Filter logs by span attributes, e.g., using tfy.model.name for model name. See Attributes section to understand the supported options for spanAttributeKey
Gateway request metadata filtering: Filter logs based on Custom Metadata keys and values that you passed to Gateway requests.
The following example demonstrates how to retrieve request logs for OpenAI models submitted by a specific user, where custom metadata matches certain values:
The tfy-llm-gateway application name is crucial for filtering spans specifically from the LLM Gateway. This ensures you only get request logs related to your LLM operations, excluding other application traces in your tracing project.
Define the time range for your query. Use ISO 8601 format for timestamps.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Fetch all Root spans for a time interval
A root span is the top-level span in a trace hierarchy that has no parent span.Define the time range for your query. Use ISO 8601 format for timestamps.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], parent_span_ids=[""], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Fetch all spans for virtual accounts
Define the time range for your query. Use ISO 8601 format for timestamps.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], created_by_subject_types=["virtualaccount"], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Fetch all spans for a virtual account `exampleaccount`
Define the time range for your query. Use ISO 8601 format for timestamps.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], created_by_subject_slugs=["exampleaccount"], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Fetch all spans for users
Define the time range for your query. Use ISO 8601 format for timestamps.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], created_by_subject_types=["user"], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Fetch all spans for a user with email example@email.com
Define the time range for your query. Use ISO 8601 format for timestamps.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], created_by_subject_slugs=["example@email.com"], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Filter by Specific Trace ID
Fetch spans of a specific traceId
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirectionspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", trace_ids=[ "0199c25e124a70989b0455584fbbf7b7" ], application_names=["tfy-llm-gateway"], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.duration, span.span_attributes.get("tfy.span_type"))
Fetch all model spans
Filter spans by model spanType using the tfy.span_type span attribute filter with value Model.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirection, SpanAttributeFilterfrom truefoundry_sdk.types.span_attribute_filter_operator import SpanAttributeFilterOperatorspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], filters=[ SpanAttributeFilter(span_attribute_key="tfy.span_type", operator=SpanAttributeFilterOperator.EQUAL, value="Model"), ], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.span_attributes.get("tfy.span_type"))
Fetch requests with Gateway request metadata
Filter spans based on custom metadata keys and values that were passed to Gateway requests using the X-TFY-METADATA header.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirection, GatewayRequestMetadataFilterfrom truefoundry_sdk.types.gateway_request_metadata_filter_operator import GatewayRequestMetadataFilterOperatorspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], filters=[ GatewayRequestMetadataFilter(gateway_request_metadata_key="application", operator=GatewayRequestMetadataFilterOperator.EQUAL, value="booking-bot"), GatewayRequestMetadataFilter(gateway_request_metadata_key="environment", operator=GatewayRequestMetadataFilterOperator.IN, value=["staging", "production"]), ], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.span_attributes.get("tfy.span_type"))
Fetch spans with MCP in span name
Filter spans that have MCP in the span name.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirection, SpanFieldFilterfrom truefoundry_sdk.types.span_field_filter_span_field_name import SpanFieldFilterSpanFieldNamefrom truefoundry_sdk.types.span_field_filter_operator import SpanFieldFilterOperatorspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], filters=[ SpanFieldFilter(span_field_name=SpanFieldFilterSpanFieldName.SPAN_NAME, operator=SpanFieldFilterOperator.STRING_CONTAINS, value="MCP"), ], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.span_attributes.get("tfy.span_type"))
Filter model spans by model name
Fetch model spans by filtering with tfy.span_type span attribute filter with value Model, and then further filter by model name using the tfy.model.name span attribute filter.
Copy
Ask AI
from truefoundry import clientfrom truefoundry_sdk import SortDirection, SpanAttributeFilterfrom truefoundry_sdk.types.span_attribute_filter_operator import SpanAttributeFilterOperatorspans = client.traces.query_spans( tracing_project_fqn="{tenant-name}:tracing-project:tfy-default" # E.g. truefoundry:tracing-project:tfy-default", start_time="2025-10-08T00:00:00.000Z", end_time="2025-10-08T23:59:59.999Z", application_names=["tfy-llm-gateway"], filters=[ SpanAttributeFilter(span_attribute_key="tfy.model.name", operator=SpanAttributeFilterOperator.EQUAL, value="openai-main/gpt-4"), SpanAttributeFilter(span_attribute_key="tfy.span_type", operator=SpanAttributeFilterOperator.EQUAL, value="Model"), ], limit=200, sort_direction=SortDirection.DESC)# Process all spans across all pagesfor span in spans: print(span.span_name, span.span_attributes.get("tfy.model.name"))
Each span you query from LLM Gateway captures key request and model details. Recognizing these attributes helps you analyze and debug usage effectively.