Send your first trace
Tidal Telemetry ingests OpenTelemetry over HTTPS. Point an SDK or an exporter at your project endpoint with a bearer token and every LLM call arrives as a span carrying model, token counts, an estimated cost, latency and errors.
Your credentials
Every project is provisioned with its own database, its own OTLP endpoint and its own ingest token. A token is rejected on any other project's endpoint. Both values are on your onboarding page after signing up; the snippets below use placeholders.
| Endpoint | https://otlp.llmcfo.com/t/your-project |
| Protocol | http/protobuf (OTLP over HTTP) |
| Paths | /v1/traces, /v1/metrics, /v1/logs - appended by the exporter, not by you |
| Auth | Authorization: Bearer tdl_<your-project-token> |
| Rate limit | 600 requests/min per project on the beta plan |
Read the token from an environment variable or a secret store in anything you deploy. Do not commit it.
Python
One call auto-instruments OpenAI, Anthropic, LangChain, LlamaIndex, Bedrock, Ollama and vector databases, including token counts and cost estimates.
pip install tidal-telemetry
# As early as possible in your app startup:
import tidal_telemetry as tidal
tidal.init(
api_key="tdl_<your-project-token>",
project="your-project",
application_name="my-service",
environment="production",
)
# That's it — OpenAI, Anthropic, LangChain, LlamaIndex, Bedrock, Ollama,
# vector DBs and GPUs are auto-instrumented. Costs and tokens included.
# Prefer env config? Set TIDAL_API_KEY + TIDAL_PROJECT and call tidal.init().
Node.js
Same one-call auto-instrumentation for TypeScript and JavaScript services.
npm install tidal-telemetry
// As early as possible in your app startup:
const tidal = require("tidal-telemetry");
tidal.init({
apiKey: "tdl_<your-project-token>",
project: "your-project",
applicationName: "my-service",
environment: "production",
});
// Auto-instruments OpenAI, Anthropic, and other supported LLM SDKs.
// Prefer env config? Set TIDAL_API_KEY + TIDAL_PROJECT and call tidal.init().
Plain OpenTelemetry (no SDK)
Ingest is standard OTLP over HTTPS, so any OpenTelemetry SDK in any language works with environment variables alone. Set the base endpoint only - exporters append /v1/traces, /v1/metrics and /v1/logs themselves.
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.llmcfo.com/t/your-project
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer tdl_<your-project-token>"
OTEL_SERVICE_NAME=my-service
Zero-code instrumentation
For a Python application you cannot or would rather not edit, the OpenTelemetry distro wraps the entrypoint with no source changes.
# Zero-code OpenTelemetry (any Python app, no source changes):
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.llmcfo.com/t/your-project \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer tdl_<your-project-token>" \
OTEL_SERVICE_NAME=my-service \
opentelemetry-instrument python app.py
Docker
Environment variables on the instrumented service; the SDK inside the container picks them up.
# docker-compose.yml — add to the service you want instrumented:
services:
app:
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: https://otlp.llmcfo.com/t/your-project
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
OTEL_EXPORTER_OTLP_HEADERS: Authorization=Bearer tdl_<your-project-token>
OTEL_SERVICE_NAME: my-service
# Plain docker run:
docker run \
-e OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.llmcfo.com/t/your-project \
-e OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
-e "OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer tdl_<your-project-token>" \
-e OTEL_SERVICE_NAME=my-service \
my-image
Kubernetes
Keep the token in a Secret and envFrom it. Never put it in the manifest of record.
apiVersion: v1
kind: Secret
metadata:
name: tidal-telemetry
type: Opaque
stringData:
OTEL_EXPORTER_OTLP_ENDPOINT: https://otlp.llmcfo.com/t/your-project
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
OTEL_EXPORTER_OTLP_HEADERS: Authorization=Bearer tdl_<your-project-token>
---
# In your Deployment's container spec:
# envFrom:
# - secretRef:
# name: tidal-telemetry
# env:
# - name: OTEL_SERVICE_NAME
# value: my-service
#
# kubectl apply -f tidal-telemetry.yaml && kubectl rollout restart deploy/my-app
Verify ingestion
An empty payload proves the endpoint and token are good without sending data. Then trigger one real LLM call and check the dashboard.
curl -sS -X POST "https://otlp.llmcfo.com/t/your-project/v1/traces" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer tdl_<your-project-token>" \
-d '{"resourceSpans":[]}'
# Expected response: {"partialSuccess":{}} (HTTP 200 = endpoint + token OK)
Connect the Tidal MCP server
Gives a coding agent live tools - account_status, verify_setup, send_test_trace, setup_instructions, troubleshoot - so it can confirm your setup rather than guess at it.
claude mcp add --transport http tidal https://otlp.llmcfo.com/mcp --header "Authorization: Bearer tdl_<your-project-token>"
Troubleshooting
401 unauthorized | Wrong or missing token. The header must be exactly Authorization: Bearer <token>, which in OpenTelemetry env syntax is Authorization=Bearer <token>. |
404 unknown tenant | The endpoint path is wrong. Use the exact endpoint from your onboarding page and do not append /v1/traces to the env var yourself - the exporter does that. |
429 on ingest | Per-project rate limit (600 requests/min on the beta plan). Batch spans rather than exporting one at a time; the SDK does this by default. |
| 200 OK but nothing in the dashboard | Usually SDK batching - wait about 30 seconds. Otherwise the wrong project is selected in the UI, or the process exits before the exporter flushes; call the SDK's shutdown or force-flush on exit. |
| Timeouts from inside Docker or Kubernetes | Egress or proxy rules. Run the verification curl from inside the container or pod to confirm. |
Connected the MCP server? Ask your agent to run troubleshoot - it answers from live
server-side state rather than from guesswork.
Frequently asked questions
Do I have to install the Tidal SDK?
No. Ingest is standard OTLP over HTTPS with a bearer token, so any OpenTelemetry exporter in any language can send to your project endpoint directly. The tidal-telemetry SDK is a convenience wrapper over the Apache-licensed OpenLIT SDK.
Which OTLP protocol and paths does the endpoint accept?
HTTP with protobuf encoding. The endpoint accepts /v1/traces, /v1/metrics and /v1/logs. Configure only the base endpoint - SDK exporters append those paths automatically.
Where do I find my endpoint and ingest token?
On your project onboarding page after signing up. Each project has its own endpoint and its own token, and a token is rejected on any other project's endpoint.
What is the ingest rate limit?
600 requests per minute per project on the beta plan, returned as HTTP 429 when exceeded. Span batching, which the SDKs do by default, keeps normal workloads well under it.
Why is there no data in my dashboard after a successful 200?
Almost always exporter batching - wait about 30 seconds. If it persists, check that the process is not exiting before the exporter flushes, and that the dashboard is showing the same project the token belongs to.
Next
Create a project to get your real endpoint and token, or read what this costs. Want the spend cut rather than just measured? That is LLM CFO's managed service, priced on verified savings.