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 IP address. 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.