Skip to main content
POST
Set interview state

Authorizations

Authorization
string
header
required

Supabase JWT — Authorization: Bearer <token>.

Body

application/json
position_id
string<uuid>
required

Interview definition id (interview_def_set.id) or position id (position_def_set.id) whose state should change.

Minimum string length: 1
Example:

"00000000-0000-0000-0000-000000000000"

status
enum<string> | null

New publication status: draft, active, archived, deleted, preparing, completed. For a position it cascades to its steps. Refused (422) for the AI interview step of a position, which follows its position. Activating a position whose required custom fields are empty is refused with 422 (name custom_fields). Archiving an active position sends the position-closed e-mail to candidates with open applications when the company has that notice switched on.

Available options:
draft,
active,
archived,
deleted,
preparing,
completed
lifecycle
enum<string>

Multi-stage positions only (422 for an interview): the vacancy lifecycle to move to (needs the position_lifecycle feature, else 403). Allowed moves: draft to open or cancelled; open, applications_closed and on_hold to each other and to filled, cancelled or closed; filled, cancelled and closed back to open (else 422). on_hold and cancelled need a reason_id. The publication status follows (open, applications_closed, on_hold = active; filled, cancelled, closed = archived). Moving an open position to filled, cancelled or closed archives it: when the company has the position-closed notice switched on, every candidate with an open application then gets the position-closed e-mail (at once or on the company's e-mail schedule). Send either status or lifecycle, not both.

Available options:
open,
applications_closed,
on_hold,
filled,
cancelled,
closed
Example:

"on_hold"

reason_id
string<uuid>

With lifecycle: a position status reason of the company that applies to the target lifecycle (an id from merchant-reason-list with type position_status).

note
string

With lifecycle: a note kept in the position's status history (at most 1000 characters).

Maximum string length: 1000
dry_run
boolean

true: change nothing; answer the publication status before and after, and whether the position-closed e-mail would go out and to how many candidates with an open application. It does not check whether the move is allowed (the real call can still refuse it), and leaves the embed key alone.

is_embedded
boolean | null

Controls iframe embedding of the interview on an external page. When true, ensures an embed key exists (returns embed_id/embed_signing_key, used to authenticate/sign the iframe embed). When false, removes the embed keys (disables embedding). Where it runs depends on the type: interviews, assessments and interview role-plays embed on the interview portal (https://<interview portal domain>/embed?embed_id=...); coaching sessions and coaching personas embed on the consumer (coaching) portal (https://<coaching portal domain>/embed?embed_id=..., a link built on the interview portal is forwarded there). A signed coaching embed (name, email, signature) signs the visitor in as a learner of that portal, and the session is charged to the merchant's interview credits on completion, not to the learner's coaching credits; it cannot start while the merchant has none.

Response

State updated.

Returns { embed_id, embed_signing_key } when an embed key was created/returned (is_embedded=true), otherwise { success: true }; either carries lifecycle when lifecycle was sent. With dry_run: { dry_run, status_from, status_to, close_notice } and nothing is changed.

success
boolean
required

True when the change was applied.

lifecycle
object

The lifecycle after the change; only when lifecycle was sent.