API Overview
Overview of the Consentify REST API, authentication, and error handling.
Consentify exposes four public API prefixes.
Base URL
https://consentify.dev
API Tiers
| Tier | Path | Auth | CORS | Purpose |
|---|---|---|---|---|
| Gateway API | /api/gateway | Public token (ct_) | Any origin | Token-mode widget config |
| Widget API | /api/consent/* | None | Any origin | Legacy config path and consent events, used by the widget and npm SDK |
| SDK API | /api/sdk/* | None | Any origin | @consentify/core cloud-mode config and events |
| Developer API | /api/v1/* | API key or session | None | Site management, consent data, analytics |
Authentication
The Developer API (/api/v1/*) accepts an API key sent via the x-api-key header:
curl -H "x-api-key: ck_your_api_key" https://consentify.dev/api/v1/sitesAPI keys are generated in the dashboard and use the ck_ prefix. Each key is tied to a user account and grants access to that user's sites only.
A dashboard session cookie also works: requests from a browser logged in to the dashboard are authenticated without an API key.
Error Format
All errors return a consistent JSON structure:
{
"error": "Human-readable message",
"code": "ERROR_CODE"
}| Code | Status | Description |
|---|---|---|
BAD_REQUEST | 400 | Invalid parameters |
UNAUTHORIZED | 401 | Missing or invalid API key |
FORBIDDEN | 403 | Insufficient permissions |
UPGRADE_REQUIRED | 403 | Endpoint requires the Pro plan |
NOT_FOUND | 404 | Resource not found |
RATE_LIMITED | 429 | Rate limit exceeded - check the X-RateLimit-* response headers |
INTERNAL_ERROR | 500 | Server error |
CORS
- Widget-facing endpoints (
/api/gateway*,/api/consent/*,/api/sdk/*): Any origin allowed -GET,POST,OPTIONS - Developer API (
/api/v1/*): No CORS headers (API key auth, not browser-facing)
TypeScript Types
type ConsentAction = "accept_all" | "reject_all" | "customize";
interface Category {
key: string;
name: string;
description: string;
required: boolean;
default: boolean;
}
interface ConsentEvent {
siteId: string;
action: ConsentAction;
categories?: Record<string, boolean>;
visitorHash: string;
policyVersion?: string;
}