Skip to main content

API Reference

Interact with Illumera programmatically. The REST API lets you sync talent data, manage projects, and query match scores from your internal systems.

Authentication​

Illumera uses Clerk for identity management. Include a valid JWT in the Authorization header for every API request. Obtain your token from the Clerk session after signing in.

curl -X GET https://api.illumera.us/api/people \
-H "Authorization: Bearer YOUR_CLERK_JWT" \
-H "Content-Type: application/json"

Most API routes require authentication. A small number of routes are publicly accessible without a token — including the health check endpoint (/api/healthz), waitlist submission (/api/waitlist), analytics ingestion (/api/analytics), and the marketing-site preview feed (/api/preview/*). All other routes return 401 Unauthorized when no valid JWT is provided. Requests from users without the required role return 403 Forbidden.

Key Endpoints​

The complete machine-readable API specification is available in the repository at lib/api-spec/openapi.yaml. The endpoints below are a representative sample.

GET /api/people​

List talent profiles accessible to your tenant. Supports filtering by skill, availability, seniority, rate range, work type, and visibility scope. Paginated via limit and offset query parameters. Requires company_admin or platform_admin role.

POST /api/projects​

Create a new project for your company. Requires company_admin or platform_admin role. See the OpenAPI spec for the required request body schema.

GET /api/engagements​

Retrieve engagements. Scoped by role — company admins see all company engagements; talent see their own.

GET /api/slots/:id/matches​

Returns ranked candidate matches for a project slot, including six-dimension spider scores. Keyed by slot ID. Requires company_member, company_admin, or platform_admin role.

GET /api/users/me​

Returns the authenticated user's profile, roles, and onboarding status.

Error Handling​

The API returns standard HTTP status codes. Error responses include a JSON body:

{
"error": "Start date must be before end date."
}
StatusMeaning
400Bad Request — validation error in request body or query params
401Unauthorized — missing or invalid JWT
403Forbidden — authenticated but insufficient role
404Not Found — resource does not exist or is not accessible to your tenant
422Unprocessable — business logic violation (e.g., slot already filled)
500Internal Server Error — unexpected server-side failure

Rate Limits​

Rate limiting is active on most routes. Routes under /healthz, /webhooks/, and /internal/ bypass rate limiting entirely. For all other routes, limits are enforced using a 60-second sliding window keyed by role tier and caller identity — the authenticated user when signed in, or the client IP for unauthenticated requests. Tier classification is based on the roles attached to the authenticated user's session:

Role tierDefault limit
platform_admin300 requests / minute
person60 requests / minute
Unauthenticated / all other roles60 requests / minute
Current behavior

company_admin and company_member users are currently classified in the 60 RPM tier alongside person users. The 120 RPM company-tier threshold exists in the rate limiter configuration but is not yet mapped to the company_admin / company_member roles.

Default limits are configurable via feature flags (rate_limit_admin_rpm, rate_limit_company_rpm, rate_limit_person_rpm) without a deployment.

Responses from rate-limited routes include two headers (bypassed routes do not set these):

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57

When strict mode is enabled (the default), exceeding the limit returns 429 Too Many Requests. When soft mode is active the request is allowed but the response includes an X-RateLimit-Warning header. The mode is toggled via the rate_limit_strict_mode feature flag.

Public authentication bypass and service routes (/healthz, /webhooks/*, /internal/*) are excluded from rate limiting as noted above.