Authentication
All requests to /api/v1/* require a valid API key sent as a bearer token, except the two public endpoints — GET /verify/:code and GET /openapi.json:
Authorization: Bearer certify_live_...
A key is necessary, not sufficient
API access is entitlement-gated on top of the key. Every authenticated request re-checks that the owning account is on the Business plan or holds an active partner contract. A perfectly valid key on an account that has since downgraded or whose partner contract lapsed returns:
{
"error": {
"code": "forbidden",
"message": "API access requires a Business plan. Upgrade to connect Certify+ to your own systems."
}
}
This is a 403 with code forbidden — distinct from insufficient_scope, which means the key itself is missing a scope. If your integration starts returning 403 without a code change on your side, check the plan before you check the key.
Key format
Keys are prefixed with certify_live_ followed by 32 alphanumeric characters. Only the prefix plus the first 8 characters are shown back to you in the dashboard — the full key is only visible once at creation time.
Scopes
Each key is issued with one or more scopes. Requests outside a key's scopes return 403 insufficient_scope.
| Scope | Grants |
|---|---|
| templates:read | GET /templates, GET /templates/:id |
| certificates:read | GET /certificates, GET /certificates/:id, GET /certificates/:id/pdf, GET /certificates/:id/emails, GET /usage |
| certificates:write | POST /certificates, POST /certificates/:id/revoke, POST /certificates/:id/send |
GET /verify/:code requires no scope and no key.
Calling from a browser
Server-to-server is the intended shape — see the security notes below. For partner dashboards that must call the API from browser JavaScript, /api/v1/* responses carry CORS headers, but only for allowlisted origins. Requests from any other origin get no Access-Control-Allow-Origin and the browser blocks the response.
- Allowlisted today:
*.cybernestsolution.com,*.eneda-ph.com(apex included), andhttp://localhost:<port>for local development. - Preflight
OPTIONSrequests are answered with204. - Permitted methods are
GET,POST,OPTIONS; permitted request headers areAuthorizationandContent-Type.
To have an origin added, reach out via contact.
Rotation
Keys have no expiry. To rotate:
- Create a new key with the same scopes.
- Deploy the new key to your integration.
- Once traffic has shifted, revoke the old key in Settings → API Keys.
Revoked keys stop working immediately — there is no grace period.
Security
- Never commit keys to source control. Use environment variables or a secret manager.
- Never ship keys to the browser. Keys act on your behalf — anyone holding one can issue certificates against your quota. The CORS allowlist exists for partner dashboards that proxy through their own backend or scope keys tightly; it is not a licence to embed a write-scoped key in client-side JavaScript.
- Scope aggressively. If an integration only reads, issue a key with just
:readscopes. - Monitor usage.
last_used_atupdates on every request; surprising activity is a rotation signal.