curl --request POST \
--url https://cool.jobmojito.com/functions/v1/job-interview-set-state \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"position_id": "00000000-0000-0000-0000-000000000000",
"lifecycle": "on_hold",
"reason_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"note": "<string>",
"dry_run": true,
"is_embedded": true
}
'import requests
url = "https://cool.jobmojito.com/functions/v1/job-interview-set-state"
payload = {
"position_id": "00000000-0000-0000-0000-000000000000",
"lifecycle": "on_hold",
"reason_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"note": "<string>",
"dry_run": True,
"is_embedded": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
position_id: '00000000-0000-0000-0000-000000000000',
lifecycle: 'on_hold',
reason_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
note: '<string>',
dry_run: true,
is_embedded: true
})
};
fetch('https://cool.jobmojito.com/functions/v1/job-interview-set-state', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://cool.jobmojito.com/functions/v1/job-interview-set-state",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'position_id' => '00000000-0000-0000-0000-000000000000',
'lifecycle' => 'on_hold',
'reason_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'note' => '<string>',
'dry_run' => true,
'is_embedded' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://cool.jobmojito.com/functions/v1/job-interview-set-state"
payload := strings.NewReader("{\n \"position_id\": \"00000000-0000-0000-0000-000000000000\",\n \"lifecycle\": \"on_hold\",\n \"reason_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"note\": \"<string>\",\n \"dry_run\": true,\n \"is_embedded\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://cool.jobmojito.com/functions/v1/job-interview-set-state")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"position_id\": \"00000000-0000-0000-0000-000000000000\",\n \"lifecycle\": \"on_hold\",\n \"reason_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"note\": \"<string>\",\n \"dry_run\": true,\n \"is_embedded\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://cool.jobmojito.com/functions/v1/job-interview-set-state")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"position_id\": \"00000000-0000-0000-0000-000000000000\",\n \"lifecycle\": \"on_hold\",\n \"reason_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"note\": \"<string>\",\n \"dry_run\": true,\n \"is_embedded\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"lifecycle": {
"status": "open",
"publication_status": "draft",
"reason": "<string>",
"note": "<string>"
}
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}Set interview state
Changes the publication status of an interview or position (draft, active, archived, preparing, completed, deleted), the vacancy lifecycle of a position (open, applications_closed, on_hold, filled, cancelled, closed), and/or manages its embed key. Provide at least one of status, lifecycle or is_embedded. The id is read with your own access first: an id you cannot see answers 404. 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).
curl --request POST \
--url https://cool.jobmojito.com/functions/v1/job-interview-set-state \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"position_id": "00000000-0000-0000-0000-000000000000",
"lifecycle": "on_hold",
"reason_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"note": "<string>",
"dry_run": true,
"is_embedded": true
}
'import requests
url = "https://cool.jobmojito.com/functions/v1/job-interview-set-state"
payload = {
"position_id": "00000000-0000-0000-0000-000000000000",
"lifecycle": "on_hold",
"reason_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"note": "<string>",
"dry_run": True,
"is_embedded": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
position_id: '00000000-0000-0000-0000-000000000000',
lifecycle: 'on_hold',
reason_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
note: '<string>',
dry_run: true,
is_embedded: true
})
};
fetch('https://cool.jobmojito.com/functions/v1/job-interview-set-state', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://cool.jobmojito.com/functions/v1/job-interview-set-state",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'position_id' => '00000000-0000-0000-0000-000000000000',
'lifecycle' => 'on_hold',
'reason_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'note' => '<string>',
'dry_run' => true,
'is_embedded' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://cool.jobmojito.com/functions/v1/job-interview-set-state"
payload := strings.NewReader("{\n \"position_id\": \"00000000-0000-0000-0000-000000000000\",\n \"lifecycle\": \"on_hold\",\n \"reason_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"note\": \"<string>\",\n \"dry_run\": true,\n \"is_embedded\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://cool.jobmojito.com/functions/v1/job-interview-set-state")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"position_id\": \"00000000-0000-0000-0000-000000000000\",\n \"lifecycle\": \"on_hold\",\n \"reason_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"note\": \"<string>\",\n \"dry_run\": true,\n \"is_embedded\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://cool.jobmojito.com/functions/v1/job-interview-set-state")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"position_id\": \"00000000-0000-0000-0000-000000000000\",\n \"lifecycle\": \"on_hold\",\n \"reason_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"note\": \"<string>\",\n \"dry_run\": true,\n \"is_embedded\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"lifecycle": {
"status": "open",
"publication_status": "draft",
"reason": "<string>",
"note": "<string>"
}
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}{
"error": "Field is required.",
"name": "interview_result_id"
}Authorizations
Supabase JWT — Authorization: Bearer <token>.
Body
Interview definition id (interview_def_set.id) or position id (position_def_set.id) whose state should change.
1"00000000-0000-0000-0000-000000000000"
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.
draft, active, archived, deleted, preparing, completed 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.
open, applications_closed, on_hold, filled, cancelled, closed "on_hold"
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).
With lifecycle: a note kept in the position's status history (at most 1000 characters).
1000true: 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.
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.
- Option 1
- Option 2
- Option 3
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.