Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.aansi.qode.world/llms.txt

Use this file to discover all available pages before exploring further.

Authentication

There are two distinct auth schemes — pick the one that matches the endpoint.

Authorization: Bearer <api-key> (most endpoints)

POST /interviews and GET /jobs require a Bearer API key minted via the admin endpoint:
Authorization: Bearer qint_mJTqNVL41YK6UqzAojxzbznkCaSfQDRP
  • Keys start with the prefix qint_.
  • Only a SHA-256 hash is persisted server-side; the plaintext is shown exactly once at creation time. Lose it and you must mint a new key.
  • Keys can be revoked at any time via DELETE /admin/api-keys/{id}.
  • The key carries a bound userId and organizationId. All downstream PTP calls happen as that user.

x-admin-secret: <shared-secret> (admin endpoints only)

POST /admin/api-keys and DELETE /admin/api-keys/{id} require a shared admin secret configured via the ADMIN_SECRET env var:
x-admin-secret: 3fb5ff63-0b36-4a95-b2c5-1d4705c3578c
Do not expose this header to end users.

Response envelope

Every endpoint returns a JSON envelope of the form:
{ "success": true,  "data": { ... } }
…or, on error:
{ "status": 401, "errors": "Invalid API key" }
errors is either a human-readable string or, on Zod validation failure, an array of issue objects.

Rate limits and idempotency

There are no hard rate limits at the moment, but every request is recorded in aansi_actions with apiKeyId, userId, organizationId, request body, response body, status, error message, and duration. POST /interviews is not idempotent — calling it twice with the same payload will create two interviews. If you need at-most-once semantics, dedupe client-side before calling.

CV fallback

POST /interviews accepts a cv_link. The wrapper downloads it (30 s timeout) and uploads it to PTP. If either step fails — network error, 404, timeout, unexpected response — the wrapper transparently falls back to creating a candidate from the email alone. The interview is still created; only the candidate’s parsed profile is empty.