Skip to navigation

Stream logs to a SIEM

Send tool call, API request, and LLM call logs to your SIEM or any OTLP backend

Your SIEM pulls tool call and API request logs from two endpoints. Gateway pushes LLM call logs to it over OTLP.

LogDelivery
Tool callsPull from GET /api/v1/logs/tool-calls/
API requestsPull from GET /api/v1/logs/api-calls/
LLM callsPush over OTLP/HTTP from the Gateway console, Settings → Telemetry export

Tool call and API request logs

The log endpoints are an Enterprise feature. If they’re not enabled, they return 403. Contact your account team.

SettingValue
AuthAuthorization: Bearer <PRODUCTION_KEY>, from Settings → API keys
OrderOldest first
PaginationPass next_cursor back as ?cursor=. Stop when has_more is false.
Filterspage_size (1-1000, default 100), created_after, created_before (ISO 8601). Tool calls: tool_name, status, connector_id. API requests: method, response_status, connector_id, toolcall_id.
Retention90 days. Alert if your collector stops, since older records can’t be recovered.
RedactionCredential headers and secret-named body fields are redacted

First poll, then pass the cursor on every later poll:

curl -s "https://ah-api.merge.dev/api/v1/logs/tool-calls/?page_size=1000&created_after=2026-05-13T00:00:00Z" \
-H "Authorization: Bearer $PRODUCTION_KEY"
curl -s "https://ah-api.merge.dev/api/v1/logs/tool-calls/?page_size=1000&cursor=eyJ0…" \
-H "Authorization: Bearer $PRODUCTION_KEY"

The response has results, next_cursor, and has_more. Persist the last next_cursor and resume from it. Run one loop per endpoint, each with its own cursor. Dedup downstream by record ID, since retries can resend a page.

Set up your SIEM

Datadog can’t pull, so run a scheduled job that pages the endpoint and POSTs results to the Logs intake.

  • Intake: https://http-intake.logs.datadoghq.com/api/v2/logs, or the host for your Datadog site
  • Auth header: DD-API-KEY: <Datadog API key>
  • Persist next_cursor only after a batch is accepted
import requests
cursor = state.load()
ah = {"Authorization": f"Bearer {AH_PRODUCTION_KEY}"}
dd_url = "https://http-intake.logs.datadoghq.com/api/v2/logs"
dd = {"Content-Type": "application/json", "DD-API-KEY": DD_API_KEY}
while True:
params = {"page_size": 1000}
if cursor:
params["cursor"] = cursor
else:
params["created_after"] = "2026-05-13T00:00:00Z"
body = requests.get(
"https://ah-api.merge.dev/api/v1/logs/tool-calls/", headers=ah, params=params, timeout=30,
).json()
batch = [
{"ddsource": "agent-handler", "service": "ah-tool-calls",
"ddtags": "env:prod", "message": rec}
for rec in body["results"]
]
if batch:
requests.post(dd_url, headers=dd, json=batch, timeout=30).raise_for_status()
cursor = body["next_cursor"]
state.save(cursor)
if not body["has_more"]:
break

LLM calls from AI Gateway

Gateway pushes each model request as an OpenTelemetry span over OTLP/HTTP. Export covers only requests made after you create a destination. Spans carry the model, provider, token counts, and cost.

Set up a destination in the Gateway console under Settings → Telemetry export:

Your platformDestination
Datadog with LLM ObservabilityDatadog
Datadog with APM onlyDatadog (APM)
Grafana CloudGrafana Cloud (traces only)
Splunk, Sentinel, Elastic, Cribl, Sumo Logic, or another OTLP backendCustom OTLP endpoint (Enterprise)

For a platform without an OTLP/HTTP receiver, run an OpenTelemetry Collector in between. This one forwards to Splunk HEC:

otel-collector.yaml
extensions:
bearertokenauth:
token: ${env:GATEWAY_EXPORT_TOKEN}
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
auth:
authenticator: bearertokenauth
exporters:
splunk_hec:
endpoint: https://splunk.acme.com:8088/services/collector
token: ${env:SPLUNK_HEC_TOKEN}
index: merge_gateway
sourcetype: "merge:gateway:llm_calls"
service:
extensions: [bearertokenauth]
pipelines:
traces:
receivers: [otlp]
exporters: [splunk_hec]

In the Gateway console, choose Custom OTLP endpoint, enter the Collector’s base URL (https://otel.acme.com), and use GATEWAY_EXPORT_TOKEN as the bearer token. Gateway appends /v1/traces. The endpoint must be public HTTPS with no redirects.

Privacy mode is on for new destinations and strips prompt and completion content. It is separate from payload logging. Export fails silently, so alert in your SIEM when spans stop arriving.