Skip to content

API reference ​

Available onEnterprise
Who can do thisWorkspace owners and admins create keys

These are the endpoints of the Infyva public API. Paths are relative to the base URL, https://api.infyva.ai/api/v1/public. It is also shown in Settings > API keys and webhooks, under API reference on the Developer platform page.

Send your key as Authorization: Bearer infy_live_... or X-API-Key: infy_live_... on every request. Keys, scopes, limits and pagination are explained in Public API.

Generated from the OpenAPI schema

Parameters and request bodies below are generated from Infyva's OpenAPI schema. The API does not declare response schemas, so example responses, scopes and errors are written by hand from the API code and checked against it.

List jobs

GET /api/v1/public/jobs

Scope: read:interviews

Your company's jobs, newest first.

Parameters

NameInTypeDetails
statusquerystringFilter by job status: draft, active, closed or archived.
limitqueryinteger1 to 200; default 50
skipqueryintegerat least 0; default 0

Example response

{
  "data": [
    {
      "id": "6adc2869a0b4af3b1cfb32a3",
      "name": "Senior Backend Engineer",
      "job_title": "Senior Backend Engineer",
      "status": "active",
      "team_department": "Engineering",
      "total_candidates": 12,
      "created_at": "2026-10-01T09:30:00Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "skip": 0
}

List a job's candidates

GET /api/v1/public/jobs/{job_id}/candidates

Scope: read:interviews

The candidates on one job, newest first. The id of each item is the job-candidate record: pass it as candidate_id to the scheduling endpoint. It is also the candidate_id in the get-an-interview response and in the candidate.stage_changed webhook. stage can be a current stage (applied, screened, interviewed, offer, hired, rejected) or an older stage name such as resume_review. status is one of uploaded, screened, scheduled, interviewed, rejected or hired.

Parameters

NameInTypeDetails
job_idrequiredpathstring
limitqueryinteger1 to 200; default 50
skipqueryintegerat least 0; default 0

Example response

{
  "data": [
    {
      "id": "6adc286aa0b4af3b1cfb32b9",
      "job_id": "6adc2869a0b4af3b1cfb32a3",
      "name": "Maya Chen",
      "email": "maya.chen@example.com",
      "stage": "screened",
      "status": "screened",
      "screening_score": 82,
      "interview_ids": ["6adc286aa0b4af3b1cfb32ba"],
      "added_at": "2026-10-02T14:05:00Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "skip": 0
}

Errors

  • 404 Job not found (the job is not in your company).

Add a candidate

POST /api/v1/public/jobs/{job_id}/candidates

Scope: write:candidates

Adds one candidate to a job. A resume_url is stored as a link; Infyva does not download it. New candidates start with stage resume_review and status uploaded. Returns 201.

Parameters

NameInTypeDetails
job_idrequiredpathstring

Request body (JSON)

FieldTypeDetails
namerequiredstring1 to 200 characters
emailrequiredstring (email)
resume_urlstring0 to 2048 characters

Example response

{
  "id": "6adc286aa0b4af3b1cfb32c4",
  "job_id": "6adc2869a0b4af3b1cfb32a3",
  "name": "Daniel Whitaker",
  "email": "daniel.whitaker@example.com",
  "stage": "resume_review",
  "status": "uploaded",
  "resume_url": "https://files.example.com/cv/daniel-whitaker.pdf",
  "added_at": "2026-10-23T10:00:00Z"
}

Errors

  • 409 Candidate is already in this job. Here detail is an object: {"message": "Candidate is already in this job", "candidate_id": "<the existing job-candidate record id>"}.
  • 409 This email belongs to a non-candidate account.
  • 409 This candidate can't be added right now.
  • 422 resume_url must be an http(s) URL, or another field failed validation (for example an invalid email).

Schedule an interview

POST /api/v1/public/jobs/{job_id}/candidates/{candidate_id}/interviews

Scope: write:candidates

Schedules an interview for a candidate on the job and emails them their link. candidate_id is the job-candidate record id from the list or add endpoints. Leave out scheduled_date to send the link now. Leave out interview_type to use the job's default. An AI interview holds 1 credit. A Live AI interview uses 0.5 credit per minute of conversation (minutes round up, 1-minute minimum). Your company's compliance policies apply and an API key can't override them. status is scheduled, or cancelled if the email could not be delivered (the credit is then returned). Returns 201.

Parameters

NameInTypeDetails
job_idrequiredpathstring
candidate_idrequiredpathstring

Request body (JSON)

FieldTypeDetails
scheduled_datestringISO datetime; omit to send the link now
timezonestringdefault UTC
question_countinteger1 to 50
duration_minutesintegerTotal interview length, in minutes 5 to 180
link_expiration_hoursinteger1 to 720; default 72
interview_typestringone of recruiter, elite_live
elite_modestringone of structured, conversational

Example response

{
  "interview_id": "6adc2871a0b4af3b1cfb3390",
  "candidate_id": "6adc286aa0b4af3b1cfb32c4",
  "job_id": "6adc2869a0b4af3b1cfb32a3",
  "status": "scheduled",
  "scheduled_date": "2026-10-23T10:00:00+00:00",
  "question_count": 5,
  "interview_url": "https://www.infyva.ai/candidate/interviews/recruiter-session/6adc2871a0b4af3b1cfb3390?token=..."
}

Errors

  • 400 Could not schedule this interview.
  • 402 Not enough credits to schedule this interview.
  • 403 Live AI is not switched on for your workspace, there are no credits left for it, or your trial ended (Your trial ended. Choose a plan to send new invites and run Live AI interviews. Your reports stay readable.).
  • 404 Candidate not found in this job.
  • 409 The candidate already has an open interview, or your company's compliance policy blocks invites for this job until its checklist is complete (detail.code is COMPLIANCE_POLICY_BLOCKED).
  • 422 The job's language is not available for Live AI, or a field failed validation.
  • 500 Failed to schedule interview.

Get an interview

GET /api/v1/public/interviews/{interview_id}

Scope: read:interviews

Status of one interview and whether its report is ready. candidate_id is the job-candidate record id. report_status is pending, generating, completed or failed, or null before the candidate starts. scheduled_date, started_at and completed_at are passed through as stored and may have no time zone suffix; they are UTC.

Parameters

NameInTypeDetails
interview_idrequiredpathstring

Example response

{
  "id": "6adc2871a0b4af3b1cfb3390",
  "job_id": "6adc2869a0b4af3b1cfb32a3",
  "candidate_id": "6adc286aa0b4af3b1cfb32c4",
  "title": "Senior Backend Engineer",
  "status": "completed",
  "scheduled_date": "2026-10-23T10:00:00",
  "created_at": "2026-10-23T10:00:00Z",
  "started_at": "2026-10-23T15:12:00",
  "completed_at": "2026-10-23T15:41:00",
  "report_status": "completed",
  "report_available": true
}

Errors

  • 404 Interview not found.

Get a report summary

GET /api/v1/public/interviews/{interview_id}/report

Scope: read:reports

The summary of a finished report: overall score, recommendation, up to five strengths and five areas to improve, and the integrity risk level. The full report stays in Infyva. recommendation is the report's verdict as stored, for AI interview reports usually Hire, Needs Follow-up or Reject; it can be null, for example on Live AI reports. integrity_risk_level is LOW_RISK, MEDIUM_RISK, HIGH_RISK or CRITICAL, or null when no integrity data was collected.

Parameters

NameInTypeDetails
interview_idrequiredpathstring

Example response

{
  "report_id": "6adc286ba0b4af3b1cfb32de",
  "interview_id": "6adc2871a0b4af3b1cfb3390",
  "overall_score": 76,
  "recommendation": "Hire",
  "performance_summary": {},
  "strengths": ["Explains trade-offs clearly"],
  "areas_for_improvement": ["Testing strategy was thin"],
  "integrity_risk_level": "LOW_RISK",
  "completed_at": "2026-10-23T15:41:00",
  "created_at": "2026-10-23T15:43:00"
}

Errors

  • 404 Report is not ready yet.

Pull the audit log

GET /api/v1/public/audit-log

Scope: read:audit_log · Also needs the audit log, which is on Enterprise.

Your workspace audit log as NDJSON: one event per line, oldest first, in the infyva.audit.v1 shape. Pass the X-Next-Cursor header from the last response as after to continue. The X-Event-Count header says how many events came back. Each pull is itself written to the audit log.

Parameters

NameInTypeDetails
afterquerystringCursor from the previous response's X-Next-Cursor header.
sincequerystring (date-time)Only events at or after this time (ISO 8601).
limitqueryintegerEvents per response, 1 to 5000. 1 to 5000; default 1000

Example response

{"action": "sso.login.succeeded", "actor_email": "maya.chen@example.com", "actor_is_infyva_support": false, "actor_system": null, "actor_user_id": "6adc2867a0b4af3b1cfb3290", "details": {}, "id": "6adc2899a0b4af3b1cfb3401", "ip_address": "203.0.113.10", "organization_id": "6adc2866a0b4af3b1cfb3288", "resource_id": null, "resource_type": "sso", "schema": "infyva.audit.v1", "target_email": null, "target_user_id": null, "timestamp": "2026-10-23T09:00:00Z", "user_agent": "Mozilla/5.0"}

Errors

  • 400 The cursor is not valid.
  • 403 The audit log is included on the Enterprise plan.

Next steps ​