Developer documentation
API keys, scopes and access
Issue least-privilege credentials, restrict their origin and rotate without losing control.
Who can create keys
API keys belong to an institution, never to an individual subject. An institution OWNER or ADMIN signs in to the member dashboard and opens Dashboard → API keys. Those roles can create, rotate and revoke credentials. A DEVELOPER can inspect key metadata but cannot reveal secrets or change credentials; other institution roles cannot access the key inventory.
A key cannot mint another key
Creation and rotation require an authenticated institutional user session with api_keys.create permission. API-key scopes deliberately do not include credential administration, so a compromised workload key cannot create replacements or expand its own access.
Create a key in the dashboard
- Sign in with an institution OWNER or ADMIN account.
- Open Dashboard → API keys and choose Create API key.
- Give the key a workload-specific name, such as Production reporting service. Do not name it after a person.
- Choose test or live. Test keys begin rcn_test_; live keys begin rcn_live_.
- Select only the scopes needed by this workload.
- Optionally enter IPv4 or IPv6 source CIDR ranges and an expiry. Validate the observed production egress network before enforcing the restriction.
- Create the key and copy the complete secret directly into the workload's secret manager. It cannot be retrieved later.
- Make a low-risk verification request, confirm last-used metadata, then remove every temporary copy of the secret.
The dashboard is operational
The institutional API-key page lists active and revoked credentials, last use, expiry, environment prefix and scopes. OWNER and ADMIN users receive create, rotate and revoke controls; DEVELOPER users receive a read-only view.
Available scopes
| Scope | Allows |
|---|---|
| credit:read | Subject lookup, inquiries and credit profiles |
| credit:report | Subject creation and account listing |
| accounts:write | Single and bulk account creation |
| events:write | Single and bulk credit events |
| reports:request | Create and retrieve detailed reports |
| webhooks:manage | Create, test, inspect, rotate and disable webhooks |
Create through the API
Automation can call POST /api/v1/api-keys with an institutional user's access JWT. Do not send an existing rcn_live_ or rcn_test_ key to this endpoint. The secret field appears only in the successful creation response.
curl -X POST "$RCN_API/api/v1/api-keys" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"display_name": "Production reporting service",
"scopes": ["credit:report", "accounts:write", "events:write"],
"environment": "live",
"allowed_ips": ["203.0.113.18"],
"expires_at": "2027-02-18T00:00:00Z"
}'{
"id": "key_…",
"display_name": "Production reporting service",
"prefix": "rcn_live_…",
"secret": "rcn_live_…complete-one-time-secret…",
"scopes": ["credit:report", "accounts:write", "events:write"],
"expires_at": "2027-02-18T00:00:00Z"
}Copy once
The secret is returned only when a key is created or rotated. RCN stores a SHA-256 hash, not the recoverable secret. Put it directly into the destination secret manager, verify access, then remove any temporary copy.
Authenticate workload requests
Send the complete key as an HTTP Bearer credential. Never put it in a URL, query string, frontend bundle or NEXT_PUBLIC_ environment variable.
curl "$RCN_API/api/v1/subjects?q=Redmont" \
-H "Authorization: Bearer $RCN_API_KEY" \
-H "Accept: application/json"const response = await fetch(process.env.RCN_API_URL + "/api/v1/subjects?q=Redmont", {
headers: {
Authorization: "Bearer " + process.env.RCN_API_KEY,
Accept: "application/json",
},
});
if (!response.ok) throw new Error("RCN request failed: " + response.status);
const subjects = await response.json();import os
import httpx
with httpx.Client(
base_url=os.environ["RCN_API_URL"],
headers={"Authorization": f"Bearer {os.environ['RCN_API_KEY']}"},
timeout=10.0,
) as client:
response = client.get("/api/v1/subjects", params={"q": "Redmont"})
response.raise_for_status()
subjects = response.json()Environment, expiry and IP controls
- environment accepts only test or live and determines the rcn_test_ or rcn_live_ prefix. Test and live resources are isolated server-side.
- expires_at is optional. Expired keys return 401 and cannot be restored; create a replacement.
- allowed_ips accepts IPv4 and IPv6 CIDR ranges; a single address is normalised to a host network.
- When RCN runs behind a reverse proxy, only explicitly trusted proxy ranges may supply the client-address chain.
- Institution suspension blocks every key belonging to that institution, even when the individual key remains active.
- Successful API-key authentication updates last_used_at and usage records identify the institution and API key without storing the secret.
List and inspect keys
GET /api/v1/api-keys requires api_keys.read and returns only the authenticated institution's credentials. Results contain id, display_name, prefix, scopes, active, last_used_at and expires_at. The full secret is never listed.
curl "$RCN_API/api/v1/api-keys" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json"Use prefixes during incidents
The non-secret prefix identifies which credential generated an observed authentication attempt. Record it in deployment inventory and incident evidence without recording the full key.
Rotation and revocation
- Choose Rotate in the dashboard or POST /api/v1/api-keys/{key_id}/rotate with an OWNER or ADMIN user token.
- Store the one-time replacement secret in the destination secret manager.
- Deploy it to every authorised caller and perform a health check.
- Confirm last_used_at on the replacement and investigate attempts using the old prefix.
- Update the credential inventory, owner and next rotation date.
Rotation is immediate
The rotation endpoint revokes the old key before returning the replacement. For zero-downtime rotation, create a separate key, deploy and verify it, then revoke the old key with DELETE /api/v1/api-keys/{key_id}.
DELETE /api/v1/api-keys/{key_id} returns 204 and makes the credential unusable immediately. Key creation, rotation and revocation are written to the audit log.
Troubleshooting
| Symptom | Likely cause and response |
|---|---|
| 401 INVALID_API_KEY | Secret is missing, malformed, expired or revoked. Confirm the secret-manager value and replace the key. |
| 403 INSUFFICIENT_SCOPE | The key lacks the route's scope, the institution is not ACTIVE, or the source IP is not allowed. |
| 422 VALIDATION_ERROR | A scope is unknown, no scope was selected, environment is invalid, or another field failed validation. |
| 429 RATE_LIMIT_EXCEEDED | Wait until X-RateLimit-Reset, add jitter and investigate sustained volume. |
| Dashboard hides management actions | Only institution OWNER and ADMIN roles can create, rotate or revoke. DEVELOPER is read-only. |