Authentication
Score CRM uses API key-based authentication for the REST API. Every request, on every endpoint, is authenticated the same way: with an API key sent in the x-api-key header.
x-api-key: live_<your key>
There's no username/password and no session token — just this one header on every request.
Get your key
Each organization has one API key.
- Go to Developer Options in your dashboard sidebar.
- Choose an expiry — never, 6 months, or 1 year.
- Click Generate key.
- Copy the secret immediately. It's shown exactly once, in a banner right after generation — Score never displays the full key again, only a short prefix like
live_9f2a...for identification. Store it in a secrets manager or environment variable on your backend before you navigate away.
If you regenerate your key, the old one stops working immediately — there's no overlap period. Update every system using the old key before you regenerate.
Regenerate or revoke your key
Both are on the same Developer Options page and take effect immediately:
- Regenerate — issues a new key and invalidates the old one the instant the new one is created. No grace period, so update your integrations first if you can.
- Revoke — disables your key with no replacement. Irreversible; generate a new key afterward to restore API access.
Keep your key safe
x-api-key has full write access to your organization's contacts. It must never appear in client-side JavaScript, a mobile app bundle, or any code a website visitor's browser can read.
Call this API from your backend only. A landing page or signup form submits to your own server first; your server — which holds the key — calls api.scorehq.co.
- Don't commit your key to source control. Use environment variables or a secrets manager.
- If a key is ever exposed (committed to a public repo, logged accidentally, etc.), request a new one immediately — a leaked key can't be selectively disabled, only replaced entirely.
- Use HTTPS on every request. Plain HTTP requests are rejected.
Handle authentication failures
A missing, invalid, expired, or revoked key all return the same response — so a caller can't distinguish "this key never existed" from "this key used to work." That's intentional: it avoids leaking key lifecycle information to anyone probing the endpoint.
{
"request_id": "req_...",
"error": {
"code": "INVALID_API_KEY",
"message": "The supplied API key is invalid"
}
}
HTTP status: 401.
What's next
- Rate Limits & Retries
- Create or Update a Contact — single-contact endpoint
- Sync a Contact Batch — batch endpoint