API + MCP reference

Authentication

Every paid request — REST, MCP, webhooks — carries a single API key as a bearer token. Keys are scoped to the tenant that issued them, not the user, so rotating a key never breaks a teammate.

No API key yet? Start a 14-day free trial of any tier. A card is required at trial start (no charge until day 14; cancel anytime). Your first key is issued automatically when the trial activates.

API keys

Keys look like th_live_d3a7...8c41 — a fixed th_live_ prefix plus a high-entropy random tail. The secret is shown once, at issue time. Store it in your secrets manager immediately; we retain only an Argon2id hash plus the last 4 characters.

issue + revoke a key
# Sign in to the web UI -> Team -> API keys -> "New key"# Or via the management API (Team-tier admins): curl -X POST https://api.terminal.house/v1/team/api-keys \  -H "Authorization: Bearer th_live_d3a7...8c41" \  -H "Content-Type: application/json" \  -d '{    "label": "production · 2026-Q2"  }' # Response:# {#   "id": "01H9X...",#   "label": "production · 2026-Q2",#   "last4": "8c41",#   "secret": "th_live_d3a7...8c41",   <- shown ONCE; store it now#   "member_id": "01H8...",#   "revoked": false# }

You can also issue + revoke keys interactively at terminal.house/api-keys.

Bearer header

Pass the key on every authenticated request as a Authorization: Bearer header. Keys in the URL, query string, or request body are rejected with 401.

authenticated request
curl https://api.terminal.house/v1/leads \  -H "Authorization: Bearer th_live_d3a7...8c41"

Public endpoints that don't require auth (/v1/health, /v1/public/contact) ignore the header if present.

Tier-based feature gating

The same key works across every surface your tier unlocks. Tier mismatch returns 403 with an upgrade-prompt URL — see Errors.

TierRESTMCPWebhooksCSVSeats
Starter1
Operator1
Teamup to 5
Custom6+

MCP-side auth

MCP clients (Claude Desktop, Cursor, Windsurf, etc.) persist the key in their own config file. We recommend env-var indirection so the secret never lives in a checked-in config:

~/.cursor/mcp.json
{  "mcpServers": {    "terminal.house": {      "url": "https://mcp.terminal.house/mcp",      "env": {        "TERMINAL_HOUSE_API_KEY": "${TERMINAL_HOUSE_API_KEY}"      }    }  }}

The full per-client setup walkthrough lives in MCP server documentation.

Rotation + revocation

We recommend rotating keys every 90 days. There's no forced expiry (we won't silently invalidate a working key), but the web UI shows a soft reminder when a key crosses 90 days old.

Rotation is two-step: issue a new key, deploy it, then revoke the old one. Revocation is immediate — the next request with the revoked key gets 401.

revoke a key
curl -X DELETE https://api.terminal.house/v1/team/api-keys/01H9X... \  -H "Authorization: Bearer th_live_d3a7...8c41" # Response: 204 No Content

If a key may have leaked

Revoke immediately. Don't wait for the rotation window. If you suspect a broader compromise (e.g. the key was in a commit pushed to a public repo), revoke every active key on the tenant and rotate webhook signing secrets too. Contact security@terminal.house if you need help auditing what was accessed.