Guide
Authentication
Every request carries an API key. The key acts as the member who created it, narrowed by the scopes it was given.
API keys
An API key belongs to one organization and looks like cp_live_ followed by a random string. Create keys in the panel under Settings → API keys (Inställningar → API-nycklar). Each key has:
- A name, so you can tell your CRM sync from your reporting job later.
- Scopes —
read,write,admin. See Scopes. - A rate limit per minute — 120 unless you set another, up to 10 000. See Rate limits.
- An optional expiry date, after which it stops working.
The secret is shown once, when the key is created. Closepact stores only a hash of it, so a lost key cannot be shown again — create a new one and revoke the old.
Sending the key
Send the key in the Authorization header as a Bearer token, on every request, over HTTPS. There is no other way to pass it — not as a query parameter, not in the body.
GET /v1/api/me HTTP/1.1
Host: api.closepact.com
Authorization: Bearer cp_live_Hx3p…The quickest way to check a key is GET /me, which returns the key, its organization, the member it acts as and the modules the organization holds:
curl 'https://api.closepact.com/v1/api/me' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"A missing header is 401 missing_api_key. A key that does not exist, is revoked or has expired is 401 invalid_api_key.
Scopes
Scopes decide what kind of request a key may make at all. Give each key the least it needs.
| Scope | The key may | Typical use |
|---|---|---|
read | Make GET requests only. | Reporting, BI, a dashboard on the wall. |
write | Also POST, PUT, PATCH and DELETE — create, change and delete data. | A CRM, ERP or webshop sync. |
admin | Everything write may, and manage the integration itself: webhook endpoints, their secrets and deliveries. | Setting up webhooks from code. |
Every endpoint in the reference shows the scope it needs. A key without it gets 403 insufficient_scope, and required names the missing scope:
{
"message": "This API key is read-only. Create a key with the \"write\" scope to change data.",
"error": "insufficient_scope",
"required": "write"
}A key acts as a member
A key acts as the member who created it. It may do what that member may do in the organization — the same role permissions, the same rules about which records they can see, the same audit trail — and its scopes narrow that further. An administrator's read key still only reads; a write key created by a member who cannot delete invoices cannot delete invoices.
When the member lacks the permission an endpoint needs, the answer is 403 permission_denied, and required lists the permissions, any one of which would do. The reference shows them on each endpoint.
{
"message": "This action is unauthorized.",
"error": "permission_denied",
"required": [
"deals.edit",
"deals.manage"
]
}If the member leaves the organization or is blocked, their keys stop working at once: every request gets 401 api_key_owner_inactive. Create long-lived integration keys from an account that will stay, and keep a note of who owns each key. acting_as in GET /me tells you who a key acts as.
Expiry and revocation
A key with an expiry date stops working when that date passes. Any key can be revoked in the panel, and the next request with it fails — there is no cache to wait out. Both answer 401 invalid_api_key.
To rotate a key without downtime:
- Create a new key with the same scopes.
- Deploy it, and confirm with
GET /methat the new key is in use. - Revoke the old key.
Organization security
The organization's security settings apply to API calls exactly as to people. If it has an IP allowlist (Settings → Security & GDPR), requests from any other address get 403 ip_not_allowed, with the address that was refused in ip. Add your integration's outbound address to the list.
A suspended organization gets 403 organization_suspended on every request until it is reinstated.
Modules and 402
Closepact is sold as three modules — Proposals & e-signing, Scheduling & work orders, and Invoicing — and most endpoints belong to one of them. The reference marks which. Calling an endpoint of a module the organization has not bought answers 402 module_locked; a module that has lapsed answers 402 module_read_only to writes, while reads keep working.
GET /me lists the modules the organization holds, with writable telling you which can still be written to.
Keeping keys safe
- Use keys from your server only — never in browser JavaScript, a mobile app or anything a customer can download.
- Keep them in environment variables or a secrets manager, out of source control.
- One key per integration, with the least scope it needs, so one can be revoked without stopping the others.
- Set an expiry date on keys for short projects and tests.
- If a key leaks, revoke it straight away and create a new one.