# Send your first trace

TwoTail ingests standard OpenTelemetry. There is no SDK to install: create an
API key, send OTLP/JSON to the ingest endpoint, and your traces are live.
About 10 minutes.

- HTML version: https://www.twotail.ai/docs
- Integrations overview: https://www.twotail.ai/integrations
- Ingest reference: https://www.twotail.ai/docs/reference
- Full coding-agent prompt: https://www.twotail.ai/docs/agent-prompt.md
- Last updated: 2026-07-10

## 1. Get an API key

Create a key in the TwoTail app (https://www.twotail.ai/app) under API Keys.
Keys start with `tt_live_` and the full key is shown once, at creation, so
copy it somewhere safe. Creating and revoking keys requires an owner, admin,
or developer role on your account.

## 2. Send traces

Two paths. Most teams use the first.

### Path A: Your coding agent does it

Copy the prompt at https://www.twotail.ai/docs/agent-prompt.md into Claude
Code, Cursor, or any coding agent working on your codebase. It instruments
your agent end to end: trace structure, sessions, LLM and tool attributes,
evals. Replace `<TWOTAIL_API_KEY>` with your key (or tell your agent where to
find it), then review the diff.

Signed-in users can generate redacted and call-only privacy variants of the
prompt in the app, under Data > Integration Guide.

### Path B: Test the endpoint with curl

Send one span by hand to confirm your key works. Use a current timestamp in
nanoseconds so the trace shows up at the top of your recent traces.

```bash
curl -X POST https://www.twotail.ai/api/v1/traces \
  -H "Content-Type: application/json" \
  -H "X-API-Key: <TWOTAIL_API_KEY>" \
  -d '{
    "resourceSpans": [{
      "resource": {"attributes": [{"key": "service.name", "value": {"stringValue": "test-agent"}}]},
      "scopeSpans": [{
        "spans": [{
          "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
          "spanId": "00f067aa0ba902b7",
          "name": "test_llm_call",
          "startTimeUnixNano": 1783977600000000000,
          "endTimeUnixNano": 1783977600100000000,
          "attributes": [
            {"key": "gen_ai.system", "value": {"stringValue": "openai"}},
            {"key": "gen_ai.request.model", "value": {"stringValue": "gpt-4"}}
          ],
          "status": {"code": 1}
        }]
      }]
    }]
  }'
```

## 3. Verify

A successful request returns:

```json
{
  "success": true,
  "message": "Successfully ingested 1 spans from OTel format",
  "spans_inserted": 1
}
```

Open the app and your trace is on the Data page, under Traces. Spans that
fail to parse are skipped rather than rejected: the request still succeeds
and the skip count usually shows in `message`. `spans_inserted` is the
authoritative count, so check it matches what you sent.

## Not seeing your trace?

- **401 Unauthorized.** The `X-API-Key` header is missing, or the key is
  wrong, revoked, or expired. Keys must start with `tt_live_`.
- **Response says success but spans are missing.** Malformed spans are
  skipped, not rejected. `spans_inserted` is the authoritative count: compare
  it to what you sent, and look for "(N malformed spans skipped)" in
  `message`.
- **Trace appears with a 1970 date, or not in recent traces.** Timestamps are
  integer Unix time in nanoseconds. Millisecond or second values are accepted
  without error but land decades in the past.

## Limits

- Maximum 1,000 spans per request. Batch below that.
- OTLP/JSON only: no protobuf, no gRPC, no gzip. Protobuf-only exporters can
  route through an OpenTelemetry Collector with JSON encoding.
- Accounts pending approval are capped at 10,000 stored spans. Contact
  support@twotail.ai to lift the limit.
