API

Post jobs and receive applications for your account. Each request needs an API key. A key can only see and change jobs on that account.

1. Authenticate

Base URL:

https://app.bkkstaff.com/api/v1

Send your key on every request. Use a Bearer token (preferred) or the X-API-Key header. Ask us for a key at [email protected].

Authorization: Bearer YOUR_API_KEY

2. Create a job

POST /jobs

Creates a job on your account and returns the apply page and apply email. You do not need a second call for those links.

Send one of these bodies

Option A — fields. Send a title and a description. Add any other fields you know.

curl -X POST https://app.bkkstaff.com/api/v1/jobs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Line Cook",
    "description": "Nights and weekends on the line.",
    "category": "Hospitality",
    "work_mode": "onsite",
    "employment_type": "full_time",
    "location": "Kingston"
  }'

Option B — pasted ad. Send the full ad as text. We fill title, description, location, and pay from that text. If you also send a field (for example title), we keep your value.

curl -X POST https://app.bkkstaff.com/api/v1/jobs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Busy Kingston restaurant needs a line cook, nights & weekends..."
  }'

What you get back

HTTP 201. JSON body. Always includes:

  • id — use this to fetch the job later
  • slug — short code, also used in apply links
  • application_url — web page where a candidate applies
  • application_email — email address that receives applications
  • statuspending (not open yet) or active (open)
  • apply_modecv (default) or quiz. We do not pick this from the ad text. Send apply_mode if you want quiz.
  • payment_required — see below

If payment is not required

payment_required is false. The job opens for applications shortly. Share application_url and application_email with candidates.

{
  "id": 61,
  "slug": "j4821",
  "status": "pending",
  "title": "Line Cook",
  "apply_mode": "cv",
  "application_url": "https://app.bkkstaff.com/job/j4821",
  "application_email": "[email protected]",
  "payment_required": false
}

If payment is required

payment_required is true. The job is saved but not open. Send the account owner to pay_url. After they pay, the job opens. The apply links in the same response stay valid.

{
  "id": 61,
  "slug": "j4821",
  "status": "pending",
  "title": "Line Cook",
  "apply_mode": "cv",
  "application_url": "https://app.bkkstaff.com/job/j4821",
  "application_email": "[email protected]",
  "payment_required": true,
  "pay_url": "https://app.bkkstaff.com/dashboard/jobs/61/pay"
}

Request fields

Field Required Description
title Yes, unless you send text Job title
description Yes, unless you send text Full job post (plain text or HTML)
text Yes, unless you send title and description Full ad as one string. Same as ad_text.
summary No Short blurb
category No For example Hospitality
location No Place name, for example Kingston
work_mode No onsite, hybrid, or remote
employment_type No full_time, part_time, or contract
salary_min, salary_max No Whole numbers
salary_period No hourly, daily, weekly, monthly, or annually
salary_negotiable No true or false
apply_mode No cv (default) or quiz
locale No Language code, for example en
timezone No IANA name, for example America/Jamaica
ask_work_authorization No true to ask if the candidate may work in the country
company, email, phone No Public contact shown on this job only

3. Get a job

GET /jobs/{id or slug}

Optional. Use the id or slug from create. Returns the job fields plus accepting_applications (true when candidates can apply now).

curl https://app.bkkstaff.com/api/v1/jobs/61 \
  -H "Authorization: Bearer YOUR_API_KEY"

4. Update a job

PATCH or PUT /jobs/{id or slug}

Change title, description, summary, pay, location, or public contact. You cannot change status or payment through this call.

5. Send an application

POST /jobs/{id or slug}/applications

Use multipart/form-data if you attach a CV. The file field name is cv. A cover note without a file is allowed. Send name, or first_name and last_name.

curl -X POST https://app.bkkstaff.com/api/v1/jobs/j4821/applications \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "name=Daniel Brown" \
  -F "[email protected]" \
  -F "phone=+1876..." \
  -F "cover_note=I have five years on the line..." \
  -F "opted_in=true" \
  -F "cv=@/path/to/cv.pdf"

→ 201

{ "id": 50231, "status": "received" }

Other fields: country, timezone, cover_note, opted_in.

Errors

Failures return JSON: {"error": "code"}.

HTTP error Meaning
401 unauthorized Missing or wrong API key
404 not_found No job with that id on this account
409 duplicate This person already applied to this job
422 invalid Send title and description, or send text
422 could_not_parse_ad We could not read the pasted ad. Send title and description instead.
422 not_accepting This job is not open for applications
422 missing_name, invalid_email, missing_content Application is missing a name, a valid email, or any content
502 cv_upload_failed CV file did not save. Retry.

Chat assistant (optional)

If you use Claude or another MCP client, you can do the same work in chat. Add this server:

https://app.bkkstaff.com/mcp

Sign in once in the browser. Then you can list jobs, create a job (fields or a pasted ad), and send a candidate email. Create follows the same payment rules as POST /jobs. The assistant never charges a card; it returns a pay link when payment is due.

JSON config for some clients:

{
  "mcpServers": {
    "bkkstaff": { "url": "https://app.bkkstaff.com/mcp" }
  }
}

Need a key or help? Email [email protected].