curl --request POST \
--url https://assess.praxicraft.com/api/v1/public/jobs/create/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "<string>",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"squad_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"description_html": "<string>",
"position_types": [
"<string>"
],
"workplace_type": "<string>",
"location_text": "<string>",
"cv_required": true,
"assessment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pipeline_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://assess.praxicraft.com/api/v1/public/jobs/create/"
payload = {
"title": "<string>",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"squad_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"description_html": "<string>",
"position_types": ["<string>"],
"workplace_type": "<string>",
"location_text": "<string>",
"cv_required": True,
"assessment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pipeline_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
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({
title: '<string>',
team_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
squad_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
description_html: '<string>',
position_types: ['<string>'],
workplace_type: '<string>',
location_text: '<string>',
cv_required: true,
assessment_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
pipeline_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://assess.praxicraft.com/api/v1/public/jobs/create/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://assess.praxicraft.com/api/v1/public/jobs/create/';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
title: '<string>',
team_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
squad_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
description_html: '<string>',
position_types: ['<string>'],
workplace_type: '<string>',
location_text: '<string>',
cv_required: true,
assessment_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
pipeline_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://assess.praxicraft.com/api/v1/public/jobs/create/"
payload := strings.NewReader("{\n \"title\": \"<string>\",\n \"team_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"squad_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"description_html\": \"<string>\",\n \"position_types\": [\n \"<string>\"\n ],\n \"workplace_type\": \"<string>\",\n \"location_text\": \"<string>\",\n \"cv_required\": true,\n \"assessment_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"pipeline_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\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))
}{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"slug": "senior-data-engineer",
"title": "Senior Data Engineer",
"status": "open",
"livemode": true,
"team": {
"id": "11111111-2222-3333-4444-555555555555",
"name": "Data Hiring",
"slug": "data-hiring"
},
"position_types": [
"full_time"
],
"workplace_type": "hybrid",
"location_text": "London, UK",
"country_code": "GB",
"region": "Europe",
"expires_at": null,
"scheduled_publish_at": null,
"cv_required": true,
"auto_invite_assessment": false,
"assessment_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"assessment_slug": "senior-backend-screen",
"pipeline_id": null,
"pipeline_slug": null,
"application_count": 14,
"published_at": "2026-09-01T09:00:00Z",
"closed_at": null,
"created_at": "2026-08-28T12:00:00Z",
"updated_at": "2026-09-01T09:00:00Z",
"sample_task": null,
"description_html": "<p>Build reliable data platforms.</p>",
"rejection_visibility": "hidden",
"application_fields": [
{
"id": "f1111111-1111-1111-1111-111111111111",
"key": "years_experience",
"label": "Years of experience",
"field_type": "number",
"placeholder": "",
"help_text": "",
"is_required": true,
"sort_order": 0,
"is_active": true,
"options": [],
"created_at": "2026-08-28T12:05:00Z",
"updated_at": "2026-08-28T12:05:00Z"
}
]
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"error": {
"message": "Invalid or revoked API Key.",
"code": "INVALID_API_KEY"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}Create job opening
Required scope:
jobs:write
Creates a draft job opening. Requires team_id (alias squad_id). Optionally link assessment_id / pipeline_id, set location and workplace, then call POST /jobs/{key}/publish/ to make it apply-able.
Responses
| Status | Code | When |
|---|---|---|
201 | — | Draft job created |
400 | VALIDATION_ERROR | Missing title/team or invalid fields |
403 | PLAN_REQUIRED | Jobs not available on Free |
Authentication & rate limits (all endpoints)
| Status | Code | When |
|---|---|---|
401 | INVALID_API_KEY | Missing or invalid bearer token |
401 | EXPIRED_API_KEY | API key past its optional expires_at |
403 | INSUFFICIENT_SCOPE | API key lacks the required scope for this operation |
403 | IP_NOT_ALLOWED | Client IP is outside this key’s CIDR allowlist |
429 | RATE_LIMITED | Rate limit exceeded — plan-tiered reads/writes per organisation per hour |
curl --request POST \
--url https://assess.praxicraft.com/api/v1/public/jobs/create/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "<string>",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"squad_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"description_html": "<string>",
"position_types": [
"<string>"
],
"workplace_type": "<string>",
"location_text": "<string>",
"cv_required": true,
"assessment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pipeline_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://assess.praxicraft.com/api/v1/public/jobs/create/"
payload = {
"title": "<string>",
"team_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"squad_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"description_html": "<string>",
"position_types": ["<string>"],
"workplace_type": "<string>",
"location_text": "<string>",
"cv_required": True,
"assessment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pipeline_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
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({
title: '<string>',
team_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
squad_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
description_html: '<string>',
position_types: ['<string>'],
workplace_type: '<string>',
location_text: '<string>',
cv_required: true,
assessment_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
pipeline_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://assess.praxicraft.com/api/v1/public/jobs/create/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://assess.praxicraft.com/api/v1/public/jobs/create/';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
title: '<string>',
team_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
squad_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
description_html: '<string>',
position_types: ['<string>'],
workplace_type: '<string>',
location_text: '<string>',
cv_required: true,
assessment_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
pipeline_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://assess.praxicraft.com/api/v1/public/jobs/create/"
payload := strings.NewReader("{\n \"title\": \"<string>\",\n \"team_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"squad_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"description_html\": \"<string>\",\n \"position_types\": [\n \"<string>\"\n ],\n \"workplace_type\": \"<string>\",\n \"location_text\": \"<string>\",\n \"cv_required\": true,\n \"assessment_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"pipeline_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\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))
}{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"slug": "senior-data-engineer",
"title": "Senior Data Engineer",
"status": "open",
"livemode": true,
"team": {
"id": "11111111-2222-3333-4444-555555555555",
"name": "Data Hiring",
"slug": "data-hiring"
},
"position_types": [
"full_time"
],
"workplace_type": "hybrid",
"location_text": "London, UK",
"country_code": "GB",
"region": "Europe",
"expires_at": null,
"scheduled_publish_at": null,
"cv_required": true,
"auto_invite_assessment": false,
"assessment_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"assessment_slug": "senior-backend-screen",
"pipeline_id": null,
"pipeline_slug": null,
"application_count": 14,
"published_at": "2026-09-01T09:00:00Z",
"closed_at": null,
"created_at": "2026-08-28T12:00:00Z",
"updated_at": "2026-09-01T09:00:00Z",
"sample_task": null,
"description_html": "<p>Build reliable data platforms.</p>",
"rejection_visibility": "hidden",
"application_fields": [
{
"id": "f1111111-1111-1111-1111-111111111111",
"key": "years_experience",
"label": "Years of experience",
"field_type": "number",
"placeholder": "",
"help_text": "",
"is_required": true,
"sort_order": 0,
"is_active": true,
"options": [],
"created_at": "2026-08-28T12:05:00Z",
"updated_at": "2026-08-28T12:05:00Z"
}
]
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"error": {
"message": "Invalid or revoked API Key.",
"code": "INVALID_API_KEY"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}Authorizations
Organisation API key created in Assess → Developer → API Keys. Format: Bearer ct_live_<your-key> (live) or Bearer ct_test_<your-key> (test). Optional per-key CIDR allowlists return 403 IP_NOT_ALLOWED.
Body
111Response
100^[-a-zA-Z0-9_]+$200Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
draft, open, closed onsite, hybrid, remote, unspecified 2552100When set on a draft, Celery auto-publishes at this UTC time.
Deprecated product path. Assessment invites happen on advance / threshold actions only — never automatically on apply.
immediate, delayed, hidden When True, L4 AI CV briefs run in M3+. Requires Growth+ plan. No per-CV credits.
When True, L1-pass apps with L3 >= threshold auto-advance (no AI).
Minimum L3 score (0–100) for optional auto-advance.
^-?\d{0,4}(?:\.\d{0,2})?$