Reference
Jobs
Posting and managing jobs for a company your app manages. API key only.
List a company’s jobs
/v1/companies/{companyId}/jobsLists jobs for a company your app manages, newest first. Archived jobs are excluded unless you ask for them with status=archived.
Path parameters
| Field | Type | Description |
|---|---|---|
| companyIdrequired | string | The Tabbio company id. |
Query parameters
| Field | Type | Description |
|---|---|---|
| page | integer | 1-based page number. Defaults to 1. |
| pageSize | integer | Items per page, 1 to 100. Defaults to 25. |
| status | string | Filter by lifecycle status. Omit to list everything but archived jobs. One of |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 200
One page of jobs.
- 401
The API key is missing, expired, or revoked.
- 403
This company is not managed by your app.
curl https://server.tabbio.com/v1/companies/$COMPANY_ID/jobs \
-H "Authorization: Bearer $TABBIO_API_KEY"const response = await fetch(
`https://server.tabbio.com/v1/companies/${companyId}/jobs`,
{
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
},
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
response = requests.get(f"https://server.tabbio.com/v1/companies/{company_id}/jobs", headers=headers)
response.raise_for_status()
payload = response.json(){
"data": [
{
"id": "job_5c19d8",
"companyId": "com_7b31c4",
"title": "Regional Operations Manager",
"description": "Own the regional operations function end to end across the Gulf network, from the Dubai and Riyadh hubs through to last mile delivery.",
"status": "active",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior",
"department": "Operations",
"city": "Dubai",
"country": "United Arab Emirates",
"location": "Dubai, United Arab Emirates",
"salary": {
"min": 25000,
"max": 35000,
"currency": "AED",
"period": "monthly"
},
"salaryVisible": true,
"distribution": "tabbio_and_company",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment"
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight"
],
"niceToHave": [
"Working Arabic and English"
],
"benefits": [
"Health cover for you and your dependants"
],
"screeningQuestions": [
{
"id": "q_experience_years",
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": true,
"order": 0,
"source": "default",
"defaultKey": "experience_years"
}
],
"eligibility": {
"candidateLocation": "uae",
"experienceYears": "7_plus",
"language": "english_or_arabic",
"workEligibility": "eligible_or_sponsorship"
},
"applicationCount": 12,
"postedAt": "2026-08-20T06:00:00.000Z",
"createdAt": "2026-08-19T14:32:07.000Z",
"updatedAt": "2026-08-28T09:11:44.000Z"
},
{
"id": "job_1e04a7",
"companyId": "com_7b31c4",
"title": "Warehouse Supervisor",
"description": "Run the night shift at the Dubai cold store, covering goods in, put away and dispatch.",
"status": "draft",
"workMode": "onsite",
"employment": "full_time",
"seniority": "mid",
"department": "Operations",
"city": "Dubai",
"country": "United Arab Emirates",
"location": "Dubai, United Arab Emirates",
"salary": null,
"salaryVisible": true,
"distribution": "tabbio_and_company",
"responsibilities": [
"Run the night shift at the Dubai cold store"
],
"requirements": [
"Three years supervising a warehouse team"
],
"niceToHave": [],
"benefits": [],
"screeningQuestions": [],
"eligibility": null,
"applicationCount": 0,
"postedAt": null,
"createdAt": "2026-08-27T10:18:52.000Z",
"updatedAt": "2026-08-27T10:18:52.000Z"
}
],
"error": null,
"meta": {
"page": 1,
"pageSize": 25,
"total": 2,
"totalPages": 1
}
}Post a job
/v1/companies/{companyId}/jobsCreates a job for a company your app manages. saveAs defaults to draft; send "live" to publish immediately, which requires the full publish contract (location, salary and screening rules) to be satisfied. Send an Idempotency-Key header to make a retry safe: the header wins over an idempotencyKey in the body.
Path parameters
| Field | Type | Description |
|---|---|---|
| companyIdrequired | string | The Tabbio company id. |
Headers
| Field | Type | Description |
|---|---|---|
| Idempotency-Key | string | Your own key for this create. Retrying with the same key returns the job the first attempt created instead of posting a duplicate. |
Request body
Sent as application/json.
| Field | Type | Description |
|---|---|---|
| idempotencyKey | string | |
| saveAsrequired | string | One of |
| basicsrequired | object | |
| titlerequired | string | |
| department | string | |
| country | string | |
| city | string | |
| workModerequired | string | One of |
| employmentrequired | string | One of |
| seniorityrequired | string | One of |
| contentrequired | object | |
| summaryrequired | string | |
| responsibilitiesrequired | string[] | |
| requirementsrequired | string[] | |
| niceToHave | string[] | |
| benefits | string[] | |
| compensation | object | |
| min | number | |
| max | number | |
| currencyrequired | string | |
| periodrequired | string | One of |
| visiblerequired | boolean | |
| eligibility | object | |
| candidateLocation | string | One of |
| experienceYears | string | One of |
| language | string | One of |
| workEligibility | string | One of |
| workforceProgramme | object | |
| valuerequired | string | One of |
| note | string | |
| acknowledged | boolean | |
| questions | object[] | |
| id | string | |
| promptrequired | string | |
| typerequired | string | One of |
| requiredrequired | boolean | |
| order | integer | |
| options | string[] | |
| source | string | One of |
| defaultKey | string | One of |
| distributionrequired | string | One of |
| confidential | object | |
| enabledrequired | boolean | |
| publicLabel | string |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 201
The created job.
- 400
The body failed validation or the publish contract.
- 401
The API key is missing, expired, or revoked.
- 403
This company is not managed by your app.
curl -X POST https://server.tabbio.com/v1/companies/$COMPANY_ID/jobs \
-H "Authorization: Bearer $TABBIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"saveAs": "draft",
"basics": {
"title": "Regional Operations Manager",
"department": "Operations",
"country": "United Arab Emirates",
"city": "Dubai",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior"
},
"content": {
"summary": "Own the regional operations function end to end across the Gulf network.",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment"
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight"
],
"niceToHave": [
"Working Arabic and English"
],
"benefits": [
"Health cover for you and your dependants"
]
},
"compensation": {
"min": 25000,
"max": 35000,
"currency": "AED",
"period": "monthly",
"visible": true
},
"questions": [
{
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": true
}
],
"distribution": "tabbio_and_company"
}'const response = await fetch(
`https://server.tabbio.com/v1/companies/${companyId}/jobs`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"saveAs": "draft",
"basics": {
"title": "Regional Operations Manager",
"department": "Operations",
"country": "United Arab Emirates",
"city": "Dubai",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior"
},
"content": {
"summary": "Own the regional operations function end to end across the Gulf network.",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment"
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight"
],
"niceToHave": [
"Working Arabic and English"
],
"benefits": [
"Health cover for you and your dependants"
]
},
"compensation": {
"min": 25000,
"max": 35000,
"currency": "AED",
"period": "monthly",
"visible": true
},
"questions": [
{
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": true
}
],
"distribution": "tabbio_and_company"
}),
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
body = {
"saveAs": "draft",
"basics": {
"title": "Regional Operations Manager",
"department": "Operations",
"country": "United Arab Emirates",
"city": "Dubai",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior",
},
"content": {
"summary": "Own the regional operations function end to end across the Gulf network.",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment",
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight",
],
"niceToHave": [
"Working Arabic and English",
],
"benefits": [
"Health cover for you and your dependants",
],
},
"compensation": {
"min": 25000,
"max": 35000,
"currency": "AED",
"period": "monthly",
"visible": True,
},
"questions": [
{
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": True,
},
],
"distribution": "tabbio_and_company",
}
response = requests.post(f"https://server.tabbio.com/v1/companies/{company_id}/jobs", headers=headers, json=body)
response.raise_for_status()
payload = response.json(){
"data": {
"id": "job_5c19d8",
"companyId": "com_7b31c4",
"title": "Regional Operations Manager",
"description": "Own the regional operations function end to end across the Gulf network, from the Dubai and Riyadh hubs through to last mile delivery.",
"status": "draft",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior",
"department": "Operations",
"city": "Dubai",
"country": "United Arab Emirates",
"location": "Dubai, United Arab Emirates",
"salary": {
"min": 25000,
"max": 35000,
"currency": "AED",
"period": "monthly"
},
"salaryVisible": true,
"distribution": "tabbio_and_company",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment"
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight"
],
"niceToHave": [
"Working Arabic and English"
],
"benefits": [
"Health cover for you and your dependants"
],
"screeningQuestions": [
{
"id": "q_experience_years",
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": true,
"order": 0,
"source": "default",
"defaultKey": "experience_years"
}
],
"eligibility": {
"candidateLocation": "uae",
"experienceYears": "7_plus",
"language": "english_or_arabic",
"workEligibility": "eligible_or_sponsorship"
},
"applicationCount": 0,
"postedAt": null,
"createdAt": "2026-08-19T14:32:07.000Z",
"updatedAt": "2026-08-19T14:32:07.000Z"
},
"error": null,
"meta": null
}Get a job
/v1/jobs/{jobId}Reads one job in the employer view, so a draft you just created comes back rather than 404ing the way the candidate-facing board would. A job belonging to a company your app does not manage answers 403; an id that matches nothing answers 404.
Path parameters
| Field | Type | Description |
|---|---|---|
| jobIdrequired | string | The Tabbio job id. |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 200
The job.
- 401
The API key is missing, expired, or revoked.
- 403
The job belongs to a company your app does not manage, or the key is missing the scope.
- 404
No job with this id.
curl https://server.tabbio.com/v1/jobs/$JOB_ID \
-H "Authorization: Bearer $TABBIO_API_KEY"const response = await fetch(
`https://server.tabbio.com/v1/jobs/${jobId}`,
{
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
},
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
response = requests.get(f"https://server.tabbio.com/v1/jobs/{job_id}", headers=headers)
response.raise_for_status()
payload = response.json(){
"data": {
"id": "job_5c19d8",
"companyId": "com_7b31c4",
"title": "Regional Operations Manager",
"description": "Own the regional operations function end to end across the Gulf network, from the Dubai and Riyadh hubs through to last mile delivery.",
"status": "active",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior",
"department": "Operations",
"city": "Dubai",
"country": "United Arab Emirates",
"location": "Dubai, United Arab Emirates",
"salary": {
"min": 25000,
"max": 35000,
"currency": "AED",
"period": "monthly"
},
"salaryVisible": true,
"distribution": "tabbio_and_company",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment"
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight"
],
"niceToHave": [
"Working Arabic and English"
],
"benefits": [
"Health cover for you and your dependants"
],
"screeningQuestions": [
{
"id": "q_experience_years",
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": true,
"order": 0,
"source": "default",
"defaultKey": "experience_years"
}
],
"eligibility": {
"candidateLocation": "uae",
"experienceYears": "7_plus",
"language": "english_or_arabic",
"workEligibility": "eligible_or_sponsorship"
},
"applicationCount": 12,
"postedAt": "2026-08-20T06:00:00.000Z",
"createdAt": "2026-08-19T14:32:07.000Z",
"updatedAt": "2026-08-28T09:11:44.000Z"
},
"error": null,
"meta": null
}Update a job
/v1/jobs/{jobId}Updates the sections you send. A live job stays live and must keep satisfying the publish contract; an archived job cannot be edited.
Path parameters
| Field | Type | Description |
|---|---|---|
| jobIdrequired | string | The Tabbio job id. |
Request body
Sent as application/json.
| Field | Type | Description |
|---|---|---|
| basics | object | |
| titlerequired | string | |
| department | string | |
| country | string | |
| city | string | |
| workModerequired | string | One of |
| employmentrequired | string | One of |
| seniorityrequired | string | One of |
| content | object | |
| summaryrequired | string | |
| responsibilitiesrequired | string[] | |
| requirementsrequired | string[] | |
| niceToHave | string[] | |
| benefits | string[] | |
| compensation | object or null | |
| min | number | |
| max | number | |
| currencyrequired | string | |
| periodrequired | string | One of |
| visiblerequired | boolean | |
| eligibility | object | |
| candidateLocation | string | One of |
| experienceYears | string | One of |
| language | string | One of |
| workEligibility | string | One of |
| workforceProgramme | object | |
| valuerequired | string | One of |
| note | string | |
| acknowledged | boolean | |
| questions | object[] | |
| id | string | |
| promptrequired | string | |
| typerequired | string | One of |
| requiredrequired | boolean | |
| order | integer | |
| options | string[] | |
| source | string | One of |
| defaultKey | string | One of |
| distribution | string | One of |
| confidential | object | |
| enabledrequired | boolean | |
| publicLabel | string |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 200
The updated job.
- 400
The body failed validation or the publish contract.
- 401
The API key is missing, expired, or revoked.
- 403
The job belongs to a company your app does not manage, or the key is missing the scope.
- 404
No job with this id.
curl -X PATCH https://server.tabbio.com/v1/jobs/$JOB_ID \
-H "Authorization: Bearer $TABBIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"compensation": {
"min": 27000,
"max": 38000,
"currency": "AED",
"period": "monthly",
"visible": true
}
}'const response = await fetch(
`https://server.tabbio.com/v1/jobs/${jobId}`,
{
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"compensation": {
"min": 27000,
"max": 38000,
"currency": "AED",
"period": "monthly",
"visible": true
}
}),
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
body = {
"compensation": {
"min": 27000,
"max": 38000,
"currency": "AED",
"period": "monthly",
"visible": True,
},
}
response = requests.patch(f"https://server.tabbio.com/v1/jobs/{job_id}", headers=headers, json=body)
response.raise_for_status()
payload = response.json(){
"data": {
"id": "job_5c19d8",
"companyId": "com_7b31c4",
"title": "Regional Operations Manager",
"description": "Own the regional operations function end to end across the Gulf network, from the Dubai and Riyadh hubs through to last mile delivery.",
"status": "active",
"workMode": "onsite",
"employment": "full_time",
"seniority": "senior",
"department": "Operations",
"city": "Dubai",
"country": "United Arab Emirates",
"location": "Dubai, United Arab Emirates",
"salary": {
"min": 27000,
"max": 38000,
"currency": "AED",
"period": "monthly"
},
"salaryVisible": true,
"distribution": "tabbio_and_company",
"responsibilities": [
"Run the daily operation across three hubs",
"Own the regional cost per shipment"
],
"requirements": [
"Seven years running regional logistics operations",
"Experience with temperature controlled freight"
],
"niceToHave": [
"Working Arabic and English"
],
"benefits": [
"Health cover for you and your dependants"
],
"screeningQuestions": [
{
"id": "q_experience_years",
"prompt": "How many years of regional operations experience do you have?",
"type": "number",
"required": true,
"order": 0,
"source": "default",
"defaultKey": "experience_years"
}
],
"eligibility": {
"candidateLocation": "uae",
"experienceYears": "7_plus",
"language": "english_or_arabic",
"workEligibility": "eligible_or_sponsorship"
},
"applicationCount": 12,
"postedAt": "2026-08-20T06:00:00.000Z",
"createdAt": "2026-08-19T14:32:07.000Z",
"updatedAt": "2026-08-29T07:26:31.000Z"
},
"error": null,
"meta": null
}Archive a job
/v1/jobs/{jobId}/archiveRemoves a draft or closed job from everyday management. Archiving is never a shortcut for unpublishing: close a live job first.
Path parameters
| Field | Type | Description |
|---|---|---|
| jobIdrequired | string | The Tabbio job id. |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 200
The archived job.
- 400
A live job must be closed before it can be archived.
- 401
The API key is missing, expired, or revoked.
- 403
The job belongs to a company your app does not manage, or the key is missing the scope.
- 404
No job with this id.
curl -X POST https://server.tabbio.com/v1/jobs/$JOB_ID/archive \
-H "Authorization: Bearer $TABBIO_API_KEY"const response = await fetch(
`https://server.tabbio.com/v1/jobs/${jobId}/archive`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
},
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
response = requests.post(f"https://server.tabbio.com/v1/jobs/{job_id}/archive", headers=headers)
response.raise_for_status()
payload = response.json(){
"data": {
"id": "<id>",
"companyId": "<companyId>",
"title": "<title>",
"description": "<description>",
"status": "<status>",
"workMode": "<workMode>",
"employment": "<employment>",
"seniority": "<seniority>",
"department": "<department>",
"city": "<city>",
"country": "<country>",
"location": "<location>",
"salary": {
"min": 0,
"max": 0,
"currency": "<currency>",
"period": "monthly"
},
"salaryVisible": false,
"distribution": "<distribution>",
"responsibilities": [
"<responsibilities>"
],
"requirements": [
"<requirements>"
],
"niceToHave": [
"<niceToHave>"
],
"benefits": [
"<benefits>"
],
"screeningQuestions": [
{
"id": "<id>",
"prompt": "<prompt>",
"type": "yes_no",
"required": false,
"order": 0,
"options": [
"<options>"
],
"source": "default",
"defaultKey": "<defaultKey>"
}
],
"eligibility": {
"candidateLocation": "<candidateLocation>",
"experienceYears": "<experienceYears>",
"language": "<language>",
"workEligibility": "<workEligibility>"
},
"applicationCount": 0,
"postedAt": "<postedAt>",
"createdAt": "<createdAt>",
"updatedAt": "<updatedAt>"
},
"error": null,
"meta": null
}Close a job
/v1/jobs/{jobId}/closeTakes a live job off every public surface. Applications already received are kept, and the job can be published again later.
Path parameters
| Field | Type | Description |
|---|---|---|
| jobIdrequired | string | The Tabbio job id. |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 200
The closed job.
- 400
Only a live job can be closed.
- 401
The API key is missing, expired, or revoked.
- 403
The job belongs to a company your app does not manage, or the key is missing the scope.
- 404
No job with this id.
curl -X POST https://server.tabbio.com/v1/jobs/$JOB_ID/close \
-H "Authorization: Bearer $TABBIO_API_KEY"const response = await fetch(
`https://server.tabbio.com/v1/jobs/${jobId}/close`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
},
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
response = requests.post(f"https://server.tabbio.com/v1/jobs/{job_id}/close", headers=headers)
response.raise_for_status()
payload = response.json(){
"data": {
"id": "<id>",
"companyId": "<companyId>",
"title": "<title>",
"description": "<description>",
"status": "<status>",
"workMode": "<workMode>",
"employment": "<employment>",
"seniority": "<seniority>",
"department": "<department>",
"city": "<city>",
"country": "<country>",
"location": "<location>",
"salary": {
"min": 0,
"max": 0,
"currency": "<currency>",
"period": "monthly"
},
"salaryVisible": false,
"distribution": "<distribution>",
"responsibilities": [
"<responsibilities>"
],
"requirements": [
"<requirements>"
],
"niceToHave": [
"<niceToHave>"
],
"benefits": [
"<benefits>"
],
"screeningQuestions": [
{
"id": "<id>",
"prompt": "<prompt>",
"type": "yes_no",
"required": false,
"order": 0,
"options": [
"<options>"
],
"source": "default",
"defaultKey": "<defaultKey>"
}
],
"eligibility": {
"candidateLocation": "<candidateLocation>",
"experienceYears": "<experienceYears>",
"language": "<language>",
"workEligibility": "<workEligibility>"
},
"applicationCount": 0,
"postedAt": "<postedAt>",
"createdAt": "<createdAt>",
"updatedAt": "<updatedAt>"
},
"error": null,
"meta": null
}Publish a job
/v1/jobs/{jobId}/publishTakes a draft or closed job live. The job must satisfy the publish contract; a job that is already live is refused.
Path parameters
| Field | Type | Description |
|---|---|---|
| jobIdrequired | string | The Tabbio job id. |
Response
These fields sit inside data.
| Field | Type | Description |
|---|---|---|
| idalways | string | The Tabbio job id. |
| companyIdalways | string | The company this job belongs to. |
| titlealways | string | Job title. |
| descriptionalways | string or null | The full job description. |
| statusalways | string | draft, active, closed or archived. Only active jobs are live. |
| workModealways | string or null | onsite, hybrid or remote. |
| employmentalways | string or null | Mirrors basics.employment on create: full_time, part_time, contract or internship. |
| seniorityalways | string or null | Mirrors basics.seniority on create: entry, mid, senior, lead or executive. |
| departmentalways | string or null | Team or function. |
| cityalways | string or null | City, when the role is not fully remote. |
| countryalways | string or null | Country. |
| locationalways | string or null | City and country as one printed line. |
| salaryalways | object or null | The pay range. Null when none was set. |
| min | number | Bottom of the range. |
| max | number | Top of the range. |
| currency | string | ISO currency code, such as AED. |
| period | string | Whether the range is per month or per year. One of |
| salaryVisiblealways | boolean | Whether candidates see the range. You always see it. |
| distributionalways | string | Where the job is listed: tabbio_and_company, tabbio_only, company_page_only or hidden. Confidential roles are always tabbio_only: a masked employer is never listed on their own company page. |
| responsibilitiesalways | string[] | What the role does. |
| requirementsalways | string[] | What the role needs. |
| niceToHavealways | string[] | Optional extras. |
| benefitsalways | string[] | What the employer offers. |
| screeningQuestionsalways | object[] | Questions every applicant answers. |
| idalways | string | Stable id. Answers refer to it. |
| promptalways | string | The question the candidate sees. |
| typealways | string | How the answer is collected. One of |
| requiredalways | boolean | Whether the candidate must answer. |
| order | integer | Where it sits in the form. |
| options | string[] | The choices, for multiple_choice questions. |
| source | string | Whether Tabbio suggested the question or you wrote it. One of |
| defaultKey | string | Which suggested question this is, for the default ones. |
| eligibilityalways | object or null | Who may apply. Null when no rules were set. |
| candidateLocation | string | Where candidates must be based. |
| experienceYears | string | Minimum experience band. |
| language | string | Language requirement. |
| workEligibility | string | Work authorization requirement. |
| applicationCountalways | integer | How many people have applied so far. |
| postedAtalways | string or null | When the job first went live. Null while it is a draft. |
| createdAtalways | string | When the job was created. |
| updatedAtalways | string | When it last changed. |
Status codes
- 200
The published job.
- 400
The job cannot be published from its current status.
- 401
The API key is missing, expired, or revoked.
- 403
The job belongs to a company your app does not manage, or the key is missing the scope.
- 404
No job with this id.
curl -X POST https://server.tabbio.com/v1/jobs/$JOB_ID/publish \
-H "Authorization: Bearer $TABBIO_API_KEY"const response = await fetch(
`https://server.tabbio.com/v1/jobs/${jobId}/publish`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TABBIO_API_KEY}`,
},
},
);
const payload = await response.json();import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['TABBIO_API_KEY']}",
}
response = requests.post(f"https://server.tabbio.com/v1/jobs/{job_id}/publish", headers=headers)
response.raise_for_status()
payload = response.json(){
"data": {
"id": "<id>",
"companyId": "<companyId>",
"title": "<title>",
"description": "<description>",
"status": "<status>",
"workMode": "<workMode>",
"employment": "<employment>",
"seniority": "<seniority>",
"department": "<department>",
"city": "<city>",
"country": "<country>",
"location": "<location>",
"salary": {
"min": 0,
"max": 0,
"currency": "<currency>",
"period": "monthly"
},
"salaryVisible": false,
"distribution": "<distribution>",
"responsibilities": [
"<responsibilities>"
],
"requirements": [
"<requirements>"
],
"niceToHave": [
"<niceToHave>"
],
"benefits": [
"<benefits>"
],
"screeningQuestions": [
{
"id": "<id>",
"prompt": "<prompt>",
"type": "yes_no",
"required": false,
"order": 0,
"options": [
"<options>"
],
"source": "default",
"defaultKey": "<defaultKey>"
}
],
"eligibility": {
"candidateLocation": "<candidateLocation>",
"experienceYears": "<experienceYears>",
"language": "<language>",
"workEligibility": "<workEligibility>"
},
"applicationCount": 0,
"postedAt": "<postedAt>",
"createdAt": "<createdAt>",
"updatedAt": "<updatedAt>"
},
"error": null,
"meta": null
}Base URL https://server.tabbio.com. Every response outside the token endpoint uses the { data, error, meta } envelope.