Competitor Tracker & Co. Docs

Using API keys

Machine credentials for scripts, jobs and MCP — minting, the X-API-Key header, scopes, expiry, revoke, regenerate, rate limits and the per-key usage log.

Use an API key when no human is at the keyboard — a script, a cron job, an MCP client. Apps that sign a person in use OAuth2 instead. Both hit the same /v1/* endpoints; the only difference is the header you send. Our lead detective C. T. Lucky covers the key path here.

An API key is the right credential when no human is at the keyboard. It belongs to your organization, carries its own set of scopes and never expires unless you tell it to.

Minting a key

Any member can create a key. Open the API keys page, or call the endpoint directly:

curl -X POST "https://api.competitortracker.io/v1/api-keys" \
  -H "Authorization: Bearer $CT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nightly-digest",
    "scopes": ["competitors:read", "changes:read"],
    "expiresAt": "2026-12-31T00:00:00.000Z"
  }'

The response carries the new key. expiresAt is optional — leave it off for a key that never expires.

{
  "id": "k_2a9f...",
  "name": "nightly-digest",
  "key": "ctk_3f8c1d6e...",
  "scopes": ["competitors:read", "changes:read"],
  "expiresAt": "2026-12-31T00:00:00.000Z"
}

Heads up

The key field is shown exactly once, right here at creation. We never store it in a form we can hand back. Copy it into your secret store now. Lose it and your only move is to regenerate.

Sending the key

The key is an opaque token prefixed ctk_. Send it on the X-API-Key header — nowhere else:

# List your subjects, no human in the loop.
curl "https://api.competitortracker.io/v1/competitors" \
  -H "X-API-Key: $CT_API_KEY"

If a request carries both Authorization and X-API-Key, the API key wins. Send one or the other to keep things clear.

Scopes

A key is limited to the scopes you grant it, and you can only grant scopes within your own role's reach. A request is refused when the key lacks the scope the endpoint needs. The full catalog and the role rules live on Scopes and permissions.

Grant the narrowest set the job needs. A digest script that only reads wants competitors:read and changes:read — nothing more.

Expiry

expiresAt is optional. Set it and the key stops working the moment that time passes — a request with an expired key is rejected. Leave it off and the key runs until you revoke it.

Revoke

Revoking a key removes it from your account at once. The key stops working immediately — there's no grace window and no undo. Revoke is the move when a key leaks or a job retires.

curl -X DELETE "https://api.competitortracker.io/v1/api-keys/$KEY_ID" \
  -H "Authorization: Bearer $CT_TOKEN"

A member can revoke their own keys. An admin or owner can revoke any key in the organization.

Regenerate

Regenerating rotates the secret behind a key. The old secret stops working at once and a new one is shown — once, same as at creation.

curl -X POST "https://api.competitortracker.io/v1/api-keys/$KEY_ID/regenerate" \
  -H "Authorization: Bearer $CT_TOKEN"

Reach for regenerate when you want a fresh secret without changing the key's name or scopes — a routine rotation, or a quiet response to a secret you no longer trust. Update your secret store right away. The old one is already cold.

Rate limits

Read requests made with an API key are rate-limited per key. The current ceiling is 600 reads a minute. Cross it and the read comes back 429. Writes aren't capped.

The limit is per key, so splitting a noisy job across two keys buys you two budgets. Back off and retry when you see a 429.

Usage log

Every key keeps a log of its recent requests — the method, the path, the status code and the time. Read it per key to see what a key has been doing:

curl "https://api.competitortracker.io/v1/api-keys/$KEY_ID/usage" \
  -H "Authorization: Bearer $CT_TOKEN"

The log is your audit trail. A key making calls you don't recognize is your cue to revoke it.

What's next

On this page