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.

On this page

Account access for people and agents

New users sign up in the browser and can create up to three projects per account. Existing users sign in.

A coding agent can use MCP to inspect and verify an existing project after you give it a scoped credential. To talk to our team, use [email protected]. A human completes their signup in the browser.

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 you create a project; the snippets below use placeholders.

Endpointhttps://otlp.llmcfo.com/t/your-project
Protocolhttp/protobuf (OTLP over HTTP)
Paths/v1/traces, /v1/metrics, /v1/logs - appended by the exporter, not by you
AuthAuthorization: Bearer tdl_<your-project-token>
Rate limit600 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

The tidal-telemetry npm package is not published yet. For a Node.js service today, use an OpenTelemetry SDK or exporter with the OTLP endpoint and headers below. Set the base endpoint to your project URL and keep the token in your environment or secret store.

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
# Populates the dashboard's Environment column. Without it that column is blank.
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production

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 \
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production \
opentelemetry-instrument python app.py

LiteLLM Proxy

Already routing through a LiteLLM gateway? Turn on its OTel callback and point it here - every model call it proxies arrives as a span, with no change to the applications behind it.

# LiteLLM Proxy — config.yaml:
litellm_settings:
  callbacks: ["otel"]

# Environment for the proxy process. LiteLLM needs OTEL_EXPORTER on top of the
# standard OTel variables. Use a real space after "Bearer" - LiteLLM parses this
# variable itself with a plain split on "=" and never URL-decodes it, so the
# %20 that works for other OTel SDKs is sent literally here and rejected.
OTEL_EXPORTER=otlp_http
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.llmcfo.com/t/your-project
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer tdl_<your-project-token>"
OTEL_SERVICE_NAME=litellm-proxy
# LiteLLM sets no environment of its own; without this the dashboard's
# Environment column stays blank.
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production

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
      OTEL_RESOURCE_ATTRIBUTES: deployment.environment.name=production

# 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 \
  -e OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production \
  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>
  OTEL_RESOURCE_ATTRIBUTES: deployment.environment.name=production
---
# 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

Send a synthetic span, then look for the tidal-setup-check service in your dashboard. A successful HTTP response alone confirms transport and authentication, not storage.

NOW=$(date +%s)000000000
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":[{"resource":{"attributes":[
        {"key":"service.name","value":{"stringValue":"tidal-setup-check"}},
        {"key":"deployment.environment.name","value":{"stringValue":"production"}}]},
      "scopeSpans":[{"spans":[{
        "traceId":"'"$(openssl rand -hex 16)"'","spanId":"'"$(openssl rand -hex 8)"'",
        "name":"tidal.setup-check","kind":1,
        "startTimeUnixNano":"'"$NOW"'","endTimeUnixNano":"'"$NOW"'",
        "status":{"code":1}}]}]}]}'
# Expected: {"partialSuccess":{}} and HTTP 200.
# Then look for service "tidal-setup-check" in the dashboard within ~30s.
# Seeing it there is the real proof - a 200 alone only means auth was accepted.

Connect the Tidal MCP server

Connect an MCP client that supports streamable HTTP to https://otlp.llmcfo.com/mcp. Today it offers account_status, usage_report, verify_setup, send_test_trace, setup_instructions, troubleshoot, and get_skill. Ask your agent to run verify_setup after your first real model call, or troubleshoot if data is missing.

Ask our team for a project-scoped credential with read access for an agent that needs status, usage, and setup checks. Keep manage credentials with your account owner. Store tokens in your MCP client's secret storage. Do not paste them into an agent prompt, commit them to a repository, or share your owner token with an agent. A shell command with a literal token may remain in shell history.

claude mcp add --transport http tidal https://otlp.llmcfo.com/mcp --header "Authorization: Bearer tdl_<your-project-token>"

This command shows the header shape; use your MCP client's secure configuration for the actual token. A project credential only reaches its assigned project. The MCP server does not create human logins; sign up in the browser.

Troubleshooting

401 unauthorizedWrong or missing token. The header must be exactly Authorization: Bearer <token>, which in OpenTelemetry env syntax is Authorization=Bearer <token>.
404 unknown tenantThe 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 ingestPer-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 dashboardUsually 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 KubernetesEgress 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?

After access is approved, follow the login instructions from our team and sign in to view the project onboarding page. Each project has its own endpoint and token.

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

Sign up free to get a project with 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.