bichito
API

Authentication

Three auth modes, three headers, three audiences. Pick the right one for the route.

The bichito API uses three independent auth modes. Each mode fits a different use case; the route you call dictates which one is accepted.

ModeHeaderAudienceIssued by
JWTAuthorization: Bearer <jwt>Dashboard / your own userPOST /auth/login, POST /auth/signup, OAuth flow
Project API keyX-API-Key: sk_…The widget (anyone in your end-user's browser)Honeycomb settings → Additional API keys
MCP tokenX-MCP-Token: mcp_…AI assistants (Claude Code, Cursor, …)/me/settings/mcp

JWT (Bearer)

Used by the dashboard and any tool acting on your behalf. Signed with HS256, valid for 30 days. Carries your user id; the API maps that to your accessible hives.

Acquire one:

POST /api/v1/auth/login
content-type: application/json

{ "email": "you@example.com", "password": "supersecret" }

200
{ "access_token": "eyJ…", "token_type": "bearer" }

Then send it on every authenticated request:

GET /api/v1/teams
authorization: Bearer eyJ…

OAuth (Google / GitHub) returns the same shape via the redirect flow — /api/v1/auth/oauth/{provider}/callback ends with the token in a redirect URL.

There's no refresh token; when the JWT expires, log in again. Sign-out is client-side (clear local storage) — there's no server-side blocklist of issued tokens.

Project API key (X-API-Key)

The publishable widget key. Created per honeycomb. Only authorises ingestion to that specific honeycomb:

POST /api/v1/bugs
x-api-key: sk_3vH…
content-type: application/json

{ "title": "...", "description": "..." }

The widget pastes this key into the user's HTML — see the transparency note for why that's intentional and what protections kick in (rate limit, no read access, no settings access, revocable).

Some endpoints accept this key too — for example, GET /api/v1/widget/info (used by the widget itself to know whether to show the "Powered by" badge). They're all listed in Ingest.

MCP token (X-MCP-Token)

Per-user, scoped, designed for AI assistants. Created from /me/settings/mcp:

POST /api/v1/mcp/bugs/123/resolve
x-mcp-token: mcp_a1b2c3…

Each MCP token carries a scope set chosen at mint time (see MCP → Scopes). The route checks the required scope and returns 403 if missing.

Different concept from the project API key — the project key is per-honeycomb and publishable; the MCP token is per-user and confidential.

What if I send no auth?

Most endpoints return 401. Public endpoints (the ingest endpoint, OAuth start URLs, /health) don't need any auth.

Mixing auth headers

Don't send more than one of Authorization, X-API-Key, X-MCP-Token on the same request. The route picks the relevant one and ignores the rest, but mixing is a sign of a confused client and risks bugs when the route shape changes.

Token storage on the client

Standard browser advice:

  • JWT in localStorage (the dashboard does this). Trade-off: survives a tab close, vulnerable to XSS if you have it. We don't have an XSS surface on bichito.dev, but if you're embedding the dashboard somewhere with one, audit accordingly.
  • API key in env vars on your build, templated into the snippet. The widget then reads it from data-key.
  • MCP token in your AI tool's MCP config (e.g. ~/.config/claude/...).

Never commit a JWT or MCP token to a public repo. The widget API key is publishable so committing it is fine — but keep it in env vars anyway for rotation hygiene.

On this page