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."
}
| Status | Meaning |
|---|---|
400 | Bad Request — validation error in request body or query params |
401 | Unauthorized — missing or invalid JWT |
403 | Forbidden — authenticated but insufficient role |
404 | Not Found — resource does not exist or is not accessible to your tenant |
422 | Unprocessable — business logic violation (e.g., slot already filled) |
500 | Internal 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 tier | Default limit |
|---|---|
platform_admin | 300 requests / minute |
person | 60 requests / minute |
| Unauthenticated / all other roles | 60 requests / minute |
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.