For Creators

API Reference

Comprehensive REST reference for interviews, questions, sessions, candidates, and usage—parameters, curl examples, and response shapes


Feature coverage and additional workflows

The API supports interview context, candidate profiles, invitation emails, session completion, report media, and personal practice results. Textarea resizing and tab draft preservation are browser interactions and do not require API fields.

POST /interviews and PATCH /interviews/{id}
ccSenderOnInviteboolean= true
Enable CC for individual and bulk invitation emails.
inviteCcEmailstring | null
One CC override email; null uses the API key owner's email. Omit on PATCH to retain the saved value.
jobDescriptionstring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
resumeTextstring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
companyNamestring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
roleTitlestring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
bash
curl -sS -X PATCH "$AURAL_BASE_URL/api/v1/interviews/INTERVIEW_ID" \
  -H "Authorization: Bearer $AURAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ccSenderOnInvite":true,"inviteCcEmail":"recruiting[at]example.com","companyName":"Example","roleTitle":"Backend Engineer"}'

Set AURAL_BASE_URL to your deployment (http://localhost:3000 for local testing) and AURAL_API_KEY to your key. CC defaults on and is visible to candidates; disabling CC prevents copies even when an override is saved.

Preview and send invitations

POST /interviews/{id}/invites — ids are candidate IDs returned by candidate creation. Creating candidates does not send email.

bash
curl -sS -X POST "$AURAL_BASE_URL/api/v1/interviews/INTERVIEW_ID/invites" \
  -H "Authorization: Bearer $AURAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":["CANDIDATE_ID"],"dryRun":true}'

Review the preview, then set dryRun to false to send. Each email uses the candidate's personal /i/invite/{token} link and preserves invite-only access. Only unstarted candidates with an email and invite token are eligible.

Preview and end interview sessions

POST /interviews/{id}/sessions/end — Uses the same body, but ids are session IDs. Only IN_PROGRESS sessions are ended, using the app's activity-duration and billing logic. Completion does not generate an AI report.

json
{"ids":["SESSION_ID"],"dryRun":true}

Both bulk endpoints require MEMBER or higher. Supply 1–100 IDs; duplicates are processed once. dryRun defaults to true. Execution rechecks eligibility, so a preview does not reserve records.

json
{"data":{"dryRun":true,"results":[{"id":"CANDIDATE_ID","status":"eligible"},{"id":"OTHER_ID","status":"skipped","reason":"Not eligible"}]}}

HTTP 200 does not mean every item succeeded. Inspect each eligible, skipped, succeeded, or failed status and reason. Batches are not atomic. Email sending is not idempotent: resubmitting a whole batch may resend successful invites. Retry only known failures; investigate uncertain timeouts before resending.

Candidate and question fields

Candidate list/create responses include the profile fields below. PATCH /interviews/{id}/candidates/{candidateId} updates them alongside name, email, phone, and notes. Omitted fields remain unchanged; null clears nullable fields. name cannot be blank; email must be valid or null.

genderstring | null
Optional candidate profile detail.
educationstring | null
Optional candidate profile detail.
schoolstring | null
Optional candidate profile detail.
majorstring | null
Optional candidate profile detail.
workExperiencestring | null
Optional candidate profile detail.
birthdaystring | null
YYYY-MM-DD
graduationYearinteger | null
Graduation year.

POST /interviews/{id}/questions and PATCH /questions/{id} also accept these fields; GET returns their stored values.

descriptionstring | null
Question guidance.
starterCodeobject | null
Language-to-source map, e.g. {"python":"..."}.
validationRulesJSON | null
Configuration using the same shape as the editor.
followUpPromptsJSON | null
Configuration using the same shape as the editor.
showIfJSON | null
Configuration using the same shape as the editor.
skipIfJSON | null
Configuration using the same shape as the editor.
probeThresholdnumber | null
Short-answer probing threshold.
timeLimitSecondsinteger | null
Positive integer, or null for no per-question limit.
allowFileUploadboolean
Enable file uploads.
allowedFileTypesstring[]
Allowed file types.

Session list/detail responses include startedAt, completedAt, and lastActivityAt. IN_PROGRESS alone does not mean a participant is currently active.

Reports, media, and practices

  • GET /sessions/{id}/report: Existing summary, insights, messages, antiCheatingLog, audioRecordings, screenshots, and mediaRetention. Signed media URLs expire; fetch fresh URLs when needed. Does not generate missing AI reports.
  • GET /interviews/{id}/practices?limit=100: The key owner's practice summaries; limit is 1–500, with no cursor pagination.
  • GET /practices/{id}: session, interview, questions, and attempts including feedback, scores, and retained answer audio. Only the key owner's own practices are accessible.

Interview time is accounted within the current subscription billing period, excluding idle gaps. Practices do not consume interview session hours, but AI practice operations use AI tokens. Read GET /usage instead of hard-coding plan allowances.

Use the web/mobile app for AI interview generation/refinement, PDF/URL extraction, live voice and microphone controls, practice answer submission/grading, answer-bank editing, recording uploads, and report generation. Those interactions do not have public REST write endpoints. Webhooks and official SDKs are not provided; internal tRPC and voice WebSockets are not stable Developer API contracts.

Base URL and conventions

Base path: /api/v1. Examples below use https://aural-ai.com; substitute your deployment host.

  • Auth — Authorization: Bearer dlv_… on every request.
  • JSON — Send Content-Type: application/json for bodies unless noted.
  • Success — Most responses wrap payloads in data. Paginated lists also return cursor (opaque string or null when there is no next page).
  • Errors — JSON shaped like { "error": { "code", "message", ... } } with 4xx/5xx status codes.
  • Rate limits — 60 requests per minute per API key. When exceeded, the API returns 429 Too Many Requests with an error body; back off and retry with exponential delay.

Interviews

List interviews

GET/api/v1/interviews

Returns interviews your key can access in its projects. Each item includes question and session counts.

Query Parameters
limitinteger= 20
Page size. Minimum 1, maximum 100.
cursorstring
Opaque pagination token from the previous response’s cursor field. Omit on the first page.
Request
curl -sS "https://aural-ai.com/api/v1/interviews?limit=20" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": [
    {
      "id": "...",
      "title": "Backend screening",
      "isActive": true,
      "_count": { "questions": 3, "sessions": 12 }
    }
  ],
  "cursor": "eyJ..."
}

When cursor is null, there are no further pages. Pass the previous cursor value to continue.

Create interview

POST/api/v1/interviews

Creates an interview in your first accessible project. Requires a title; other fields use defaults below.

Request Body
titlerequiredstring
Display name for the interview template.
descriptionstring
Longer description shown in the product UI.
objectivestring
What you want to learn from candidates.
assessmentCriteriaobject[]
Array of { name, description } rubric items for evaluators.
chatEnabledboolean= true
Allow text chat in the session.
voiceEnabledboolean= false
Enable voice mode for candidates.
videoEnabledboolean= false
Enable video for candidates.
aiNamestring= Aural
Name the AI uses when speaking to candidates.
aiToneenum= PROFESSIONAL
CASUAL | PROFESSIONAL | FORMAL | FRIENDLY — interview tone.
followUpDepthenum= MODERATE
LIGHT | MODERATE | DEEP — how hard the AI probes.
languagestring= en
BCP-47 style language code for the session.
timeLimitMinutesinteger | null
Optional cap on session length in minutes.
antiCheatingEnabledboolean= false
Turn on anti-cheating signals where supported.
ccSenderOnInviteboolean= true
Enable CC for individual and bulk invitation emails.
inviteCcEmailstring | null
One CC override email; null uses the API key owner's email. Omit on PATCH to retain the saved value.
jobDescriptionstring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
resumeTextstring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
companyNamestring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
roleTitlestring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.

If your organization has reached its interview template quota, the API returns 403 with PLAN_LIMIT_EXCEEDED (see Usage & Limits).

Request
curl -sS -X POST "https://aural-ai.com/api/v1/interviews" \
  -H "Authorization: Bearer dlv_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Backend screening","voiceEnabled":true,"chatEnabled":true}'
Response 200
{
  "data": {
    "id": "...",
    "title": "Backend screening",
    "chatEnabled": true,
    "voiceEnabled": true,
    "videoEnabled": false,
    "aiTone": "PROFESSIONAL",
    "followUpDepth": "MODERATE",
    "language": "en"
  }
}

Get interview detail

GET/api/v1/interviews/:id

Returns one interview with its questions array and session count. Unknown or inaccessible ids yield 404.

No query parameters.

Request
curl -sS "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": {
    "id": "...",
    "title": "Backend screening",
    "objective": "Assess API design",
    "questions": [
      {
        "id": "...",
        "text": "Describe a recent API.",
        "type": "OPEN_ENDED",
        "order": 0
      }
    ],
    "_count": { "sessions": 12 }
  }
}

Update interview

PATCH/api/v1/interviews/:id

Partial update. Any create body field may be sent; omitted keys are left unchanged.

Request Body (all optional)
titlestring
New title.
descriptionstring
Updated description.
objectivestring
Updated objective.
assessmentCriteriaobject[]
Replace rubric with a new array of criteria.
chatEnabledboolean
Toggle chat channel.
voiceEnabledboolean
Toggle voice.
videoEnabledboolean
Toggle video.
aiNamestring
AI display name.
aiToneenum
CASUAL | PROFESSIONAL | FORMAL | FRIENDLY.
followUpDepthenum
LIGHT | MODERATE | DEEP.
languagestring
Session language code.
timeLimitMinutesinteger | null
Session time cap; null clears the cap.
antiCheatingEnabledboolean
Anti-cheating toggle.
ccSenderOnInviteboolean= true
Enable CC for individual and bulk invitation emails.
inviteCcEmailstring | null
One CC override email; null uses the API key owner's email. Omit on PATCH to retain the saved value.
jobDescriptionstring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
resumeTextstring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
companyNamestring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
roleTitlestring | null
Interview/practice context. Supply extracted text; null clears, omission on PATCH preserves.
Request
curl -sS -X PATCH "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID" \
  -H "Authorization: Bearer dlv_KEY" \
  -H "Content-Type: application/json" \
  -d '{"voiceEnabled":true}'
Response 200
{
  "data": {
    "id": "...",
    "title": "Backend screening",
    "voiceEnabled": true
  }
}

Archive interview

DELETE/api/v1/interviews/:id

Soft-archives the interview by setting isActive to false. Historical sessions remain available.

No request body.

Request
curl -sS -X DELETE "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": {
    "id": "...",
    "archived": true
  }
}

Publish interview

POST/api/v1/interviews/:id/publish

Activates the interview, turns off invite-only mode, ensures a publicSlug exists, and returns the shareable candidate URL.

No request body.

Request
curl -sS -X POST "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID/publish" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": {
    "id": "...",
    "publicSlug": "acme-backend-2025",
    "url": "https://aural-ai.com/i/acme-backend-2025"
  }
}

Questions

List questions

GET/api/v1/interviews/:id/questions

Returns all questions for the interview, sorted by order ascending.

No query parameters.

Request
curl -sS "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID/questions" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": [
    {
      "id": "...",
      "text": "Pick a design pattern.",
      "type": "SINGLE_CHOICE",
      "order": 0,
      "options": ["Singleton", "Factory", "Observer"]
    }
  ]
}

Create questions

POST/api/v1/interviews/:id/questions

Creates one or many questions. Send a single object or an array; omit order to auto-increment.

Request Body (per question)
textrequiredstring
The prompt shown to the candidate.
typeenum= OPEN_ENDED
OPEN_ENDED | SINGLE_CHOICE | MULTIPLE_CHOICE | CODING | WHITEBOARD | RESEARCH.
orderinteger
Zero-based position; auto-assigned when omitted.
requiredboolean= true
Maps to isRequired in storage.
optionsstring[]
Choice labels for SINGLE_CHOICE and MULTIPLE_CHOICE.
followUpEnabledboolean= true
Maps to probeOnShort — allow AI follow-ups.

Wrap a single question in an object, or send an array to bulk-create.

Request
curl -sS -X POST "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID/questions" \
  -H "Authorization: Bearer dlv_KEY" \
  -H "Content-Type: application/json" \
  -d '[{"text":"Pick one","type":"SINGLE_CHOICE","options":["A","B"]}]'
Response 200
{
  "data": [
    {
      "id": "...",
      "text": "Pick one",
      "type": "SINGLE_CHOICE",
      "order": 0,
      "options": ["A", "B"]
    }
  ]
}

Update question

PATCH/api/v1/questions/:id

Partial update for a single question anywhere in your accessible projects.

Request Body (all optional)
textstring
New prompt text.
typeenum
Question type enum as on create.
orderinteger
Reorder index.
requiredboolean
Updates isRequired.
optionsstring[]
Replace choice options.
followUpEnabledboolean
Updates probeOnShort.
Request
curl -sS -X PATCH "https://aural-ai.com/api/v1/questions/QUESTION_ID" \
  -H "Authorization: Bearer dlv_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order":1}'
Response 200
{
  "data": {
    "id": "...",
    "text": "Pick one",
    "order": 1,
    "type": "SINGLE_CHOICE"
  }
}

Delete question

DELETE/api/v1/questions/:id

Permanently removes the question from its interview.

No request body.

Request
curl -sS -X DELETE "https://aural-ai.com/api/v1/questions/QUESTION_ID" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": {
    "id": "...",
    "deleted": true
  }
}

Sessions

List sessions for an interview

GET/api/v1/interviews/:id/sessions

Paginated sessions with summaries and per-session message counts.

Query Parameters
limitinteger= 20
Between 1 and 100.
cursorstring
Pagination token from the prior response.

Each row includes id, status, participant fields, AI outputs (summary, insights, themes, sentiment), totalDurationSeconds, timestamps, and _count.messages.

Request
curl -sS "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID/sessions?limit=20" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": [
    {
      "id": "...",
      "status": "COMPLETED",
      "participantName": "Alex",
      "participantEmail": "alex[at]example.com",
      "summary": "Strong system design answers.",
      "insights": ["Clear tradeoff discussion"],
      "themes": ["APIs", "scalability"],
      "sentiment": "positive",
      "totalDurationSeconds": 1842,
      "createdAt": "2026-04-01T12:00:00.000Z",
      "updatedAt": "2026-04-01T12:31:00.000Z",
      "_count": { "messages": 42 }
    }
  ],
  "cursor": null
}

Get session detail

GET/api/v1/sessions/:id

Full session record including ordered messages and nested interview metadata.

No query parameters.

Request
curl -sS "https://aural-ai.com/api/v1/sessions/SESSION_ID" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": {
    "id": "...",
    "status": "COMPLETED",
    "participantName": "Alex",
    "participantEmail": "alex[at]example.com",
    "summary": "Strong system design answers.",
    "insights": ["Clear tradeoff discussion"],
    "themes": ["APIs"],
    "sentiment": "positive",
    "totalDurationSeconds": 1842,
    "createdAt": "2026-04-01T12:00:00.000Z",
    "messages": [
      {
        "id": "...",
        "role": "assistant",
        "content": "Welcome to your interview.",
        "timestamp": "2026-04-01T12:00:05.000Z"
      }
    ],
    "interview": {
      "id": "...",
      "title": "Backend screening",
      "objective": "Assess API design"
    }
  }
}

Candidates

List candidates

GET/api/v1/interviews/:id/candidates

All invite rows for the interview, including tokens and linked session ids when present.

No query parameters.

Request
curl -sS "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID/candidates" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": [
    {
      "id": "...",
      "name": "Alex",
      "email": "alex[at]example.com",
      "phone": "+1-555-0100",
      "notes": "Referral from Jane",
      "inviteToken": "...",
      "sessionId": null,
      "createdAt": "2026-04-01T10:00:00.000Z"
    }
  ]
}

Create candidates

POST/api/v1/interviews/:id/candidates

Creates invite rows and returns inviteUrl for each. Accepts one object or up to 500 in an array.

Request Body (per candidate)
namestring
Candidate display name.
emailstring
Contact email.
phonestring
Optional phone number.
notesstring
Internal notes for your team.

If session hours are exhausted for the organization, the API responds with 403, PLAN_LIMIT_EXCEEDED, and limit: "session_hours".

Request
curl -sS -X POST "https://aural-ai.com/api/v1/interviews/INTERVIEW_ID/candidates" \
  -H "Authorization: Bearer dlv_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Alex","email":"alex[at]example.com"}'
Response 200
{
  "data": [
    {
      "id": "...",
      "name": "Alex",
      "email": "alex[at]example.com",
      "inviteToken": "...",
      "inviteUrl": "https://aural-ai.com/i/acme-backend-2025?token=..."
    }
  ]
}

Usage

Organization usage and limits

GET/api/v1/usage

Snapshot of plan label and current consumption for templates, session hours, AI tokens, and seats.

No query parameters.

Request
curl -sS "https://aural-ai.com/api/v1/usage" \
  -H "Authorization: Bearer dlv_KEY"
Response 200
{
  "data": {
    "plan": "pro",
    "templates": { "used": 8, "limit": 25 },
    "session_hours": { "used": 42.5, "limit": 100 },
    "ai_tokens": { "used": 125000, "limit": 500000 },
    "seats": { "used": 5, "limit": 10 }
  }
}

Interpretation of limits, null caps, and quota errors is covered in Usage & Limits.

OpenAPI

Use the OpenAPI spec with codegen or documentation tools to stay in sync as the API evolves.