All requests to the iClosed.io API must include a valid API key. This page covers how authentication works, how to manage your keys, and how to keep them secure.
| Detail | Value |
|---|---|
| Method | Bearer token in the Authorization header |
| Token format | Must start with iclosed_ prefix |
| Scope | Keys are tied to a user and account — requests run in that context |
| Transport | HTTPS only |
Include this header on every request:
Authorization: Bearer iclosed_<your-api-key>Both Bearer (capitalised, with a space) and the iclosed_ prefix are required. No other authentication method is supported.
- Log in at app.iclosed.io
- Go to Settings → Developer → API Keys
- Click Create API Key, give it a name, and set an optional expiration date
- Copy the key immediately — it will not be shown again after you leave the page
- Store it in an environment variable or secrets manager (see Security best practices)
API access requires a Business or Enterprise plan. If you do not see an API Keys section, check your plan at iclosed.io/pricing.
| State | API behaviour |
|---|---|
| Active | Requests succeed normally |
| Expired | 401 — "message": "API key expired" |
| Revoked | 401 — "message": "Invalid API key" |
Rotating a key:
- Create a new key in Settings
- Update your integration to use the new key
- Revoke or delete the old key
curl -X GET "https://public.api.iclosed.io/v1/eventCalls?eventType=UPCOMING" \
-H "Authorization: Bearer iclosed_YOUR_API_KEY" \
-H "Content-Type: application/json"const response = await fetch('https://public.api.iclosed.io/v1/contacts', {
method: 'POST',
headers: {
'Authorization': 'Bearer iclosed_YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstName: 'Jane',
lastName: 'Doe',
email: 'jane@example.com'
})
});
const { data } = await response.json();
console.log(data.contact.id);import requests
response = requests.get(
'https://public.api.iclosed.io/v1/eventCalls',
params={'eventType': 'UPCOMING', 'limit': 20},
headers={
'Authorization': 'Bearer iclosed_YOUR_API_KEY',
'Content-Type': 'application/json'
}
)
data = response.json()- Open your request → Authorization tab
- Select Bearer Token from the Type dropdown
- Paste your full key including the
iclosed_prefix
| HTTP Code | message value | code value | Cause |
|---|---|---|---|
401 | "API key is required" | MISSING_API_KEY | Authorization header missing or token does not start with iclosed_ |
401 | "Invalid API key" | — | Key is unknown, revoked, or malformed |
401 | "API key expired" | — | Key has passed its expiration date |
403 | "Forbidden" | — | Key exists but lacks permission for this resource |
Example 401 response body:
{
"message": "API key is required",
"code": "MISSING_API_KEY"
}- Never commit keys to version control. Use environment variables,
.envfiles (git-ignored), or a secrets manager. - One key per environment. Create separate keys for production and development so you can revoke each independently.
- One key per integration. If iClosed connects to multiple tools, give each its own key.
- Set expiration dates. Short-lived keys reduce exposure if a key leaks.
- Rotate after any suspected exposure. Revoke the compromised key immediately and issue a new one.
- HTTPS only. Never send requests over plain HTTP.
| Method | Best for |
|---|---|
| API key | Server-to-server integrations for a single workspace you control |
| OAuth client | Third-party apps where each customer signs in and grants access to their own workspace |
To register an OAuth client and implement the authorization code flow, see OAuth Clients.
- OAuth Clients — Register clients, user consent, tokens, and approval
- Rate Limiting — Request limits and backoff strategy
- Errors — Full error code reference
- API Reference — All endpoints