# TracerKit REST API v1

Public REST API for TracerKit — tag management with verification. This is
the surface the TracerKit CLI, server SDKs, and AI agents consume.

- **Base URL**: `https://tracerkit.com`
- **OpenAPI 3.1 spec**: https://tracerkit.com/api/v1/openapi.json
- **Auth**: `Authorization: Bearer tkapi_...` — org-scoped API tokens
  created under Settings → API tokens (https://tracerkit.com/dashboard/settings). The
  token is shown once; every call is scoped to that organization.
- **Rate limit**: 120 requests/minute per token (429 with
  `Retry-After` when exceeded).
- **Errors**: every non-2xx response is
  `{"error": {"code": "...", "message": "..."}}` — codes:
  `unauthorized` (401), `forbidden` (403, plan gates), `not_found`
  (404), `invalid_request` (422), `rate_limited` (429),
  `internal_error` (500).
- **Revisions**: every live mutation (create/update/delete/publish/restore)
  records a tag revision attributed to the token's creator — the same
  version history the dashboard shows and restores from.
- **MCP twin**: agents that prefer MCP get the same auth + capabilities at
  `https://tracerkit.com/api/mcp` (see https://tracerkit.com/docs/install.md).

## Endpoints

### GET /api/v1/sites

The sites in the token's organization, including each site's public key and whether the loader has sent its first beacon.


```bash
curl https://tracerkit.com/api/v1/sites \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### POST /api/v1/sites

Create a site in the token's organization. Returns the site's public key and the install snippet to paste into the site-wide <head>.


```bash
curl -X POST https://tracerkit.com/api/v1/sites \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My store", "domain": "example.com"}'
```

### GET /api/v1/sites/{siteId}

One site, with its install snippet.

- `siteId`: Site id (uuid)

```bash
curl https://tracerkit.com/api/v1/sites/siteId_UUID \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### GET /api/v1/sites/{siteId}/health

Per-tag health: status (firing/degraded/silent/waiting/disabled), last fire time, and 24h fire/error counts. Use after installing the snippet to verify beacons arrive.

- `siteId`: Site id (uuid)

```bash
curl https://tracerkit.com/api/v1/sites/siteId_UUID/health \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### GET /api/v1/sites/{siteId}/tags

The managed tags for a site — live and draft, in order.

- `siteId`: Site id (uuid)

```bash
curl https://tracerkit.com/api/v1/sites/siteId_UUID/tags \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### POST /api/v1/sites/{siteId}/tags

Add a managed tag. Same validation as the dashboard: script/pixel kinds need an https src, inline needs inlineCode. Pass draft: true to create it as a draft (kept out of the live config until published). Live creates record a revision attributed to the token's creator.

- `siteId`: Site id (uuid)

```bash
curl -X POST https://tracerkit.com/api/v1/sites/siteId_UUID/tags \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "GA4", "kind": "script", "src": "https://www.googletagmanager.com/gtag/js?id=G-XXXX"}'
```

### PATCH /api/v1/sites/{siteId}/tags/{tagId}

Partial update — omitted fields keep their current values and the merged result is re-validated as a whole. enabled toggles the tag. Editing a draft edits it in place (no history until publish); editing a live tag records an "updated" revision.

- `siteId`: Site id (uuid)
- `tagId`: Tag id (uuid)

```bash
curl -X PATCH https://tracerkit.com/api/v1/sites/siteId_UUID/tags/tagId_UUID \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"loadStrategy": "lazyOnload", "enabled": true}'
```

### DELETE /api/v1/sites/{siteId}/tags/{tagId}

Delete a tag. Live tags record a "deleted" revision and can be restored from history; drafts are discarded without history.

- `siteId`: Site id (uuid)
- `tagId`: Tag id (uuid)

```bash
curl -X DELETE https://tracerkit.com/api/v1/sites/siteId_UUID/tags/tagId_UUID \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### POST /api/v1/sites/{siteId}/tags/{tagId}/publish

Publish a draft ({tagId} is the draft's id). A draft of a live tag overwrites that tag's row (its id stays stable); a standalone draft goes live in place. Records a revision exactly like a dashboard publish.

- `siteId`: Site id (uuid)
- `tagId`: Tag id (uuid)

```bash
curl -X POST https://tracerkit.com/api/v1/sites/siteId_UUID/tags/tagId_UUID/publish \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### POST /api/v1/sites/{siteId}/conversions

Post a server-side / offline conversion (Shopify or Stripe webhook, CRM stage change, B2B signup) referencing the visitor's anonymousId. TracerKit enriches it from that visitor's identity profile (click ids + hashed PII the loader collected) and enqueues it to the site's CAPI destinations for high match quality. Pass your own externalUserId to stitch the conversion to a canonical person and enrich from that user's cross-device union (identity resolution). Idempotent on (destination, eventId) so a retried webhook can't double-send. Requires the conversions:write token scope and the Server-side (CAPI) plan.

- `siteId`: Site id (uuid)

```bash
curl -X POST https://tracerkit.com/api/v1/sites/siteId_UUID/conversions \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"anonymousId": "3f0c...", "eventName": "Purchase", "eventId": "order_1234", "value": 99.5, "currency": "USD"}'
```

### GET /api/v1/sites/{siteId}/revisions

Tag change history, newest first. Snapshots are included so a client can inspect what a restore would apply.

- `siteId`: Site id (uuid)
- `limit` (query): 1-100, default 50

```bash
curl https://tracerkit.com/api/v1/sites/siteId_UUID/revisions \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

### POST /api/v1/sites/{siteId}/revisions/{revisionId}/restore

Revert a tag to a recorded snapshot — resurrects deleted tags under their original id. Snapshots are re-validated against the current tag format and obey the same plan gates as edits; the restore records its own revision.

- `siteId`: Site id (uuid)
- `revisionId`: Revision id (uuid)

```bash
curl -X POST https://tracerkit.com/api/v1/sites/siteId_UUID/revisions/revisionId_UUID/restore \
  -H "Authorization: Bearer tkapi_YOUR_TOKEN"
```

Machine-readable version of this page: https://tracerkit.com/docs/api.md (HTML: https://tracerkit.com/docs/api)
