Developers

Two ways to plug BKKStaff into your own tools: a remote MCP server so an AI assistant can run your hiring from chat, and a REST API for posting jobs and submitting applications from your own front-end.

MCP server

The Model Context Protocol (MCP) server lets you connect an AI client — Claude, or any MCP-capable app — directly to your BKKStaff account. Once connected, you can run your hiring by chatting: switch between your teams and jobs, see who applied and who's strong, search your whole past-applicant pool in plain language, read a candidate in full, post and approve jobs, pause them, and email a candidate.

It's a remote (HTTP) server, so there's nothing to install. The endpoint is:

https://app.bkkstaff.com/mcp

Connect in one click

In your client's integrations / connectors / MCP settings, add a new remote (HTTP) server and paste the URL above. Most clients pick it up from the URL alone and walk you through a one-time sign-in — you approve access to your BKKStaff dashboard once, and that's it. No tokens to copy. Authentication is standard OAuth 2.1 + PKCE.

For clients configured by JSON, add it under mcpServers:

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

A client that can only talk to local (stdio) servers can bridge to it:

npx mcp-remote https://app.bkkstaff.com/mcp

What you can do

  • Navigate — list your teams, switch the active team, list a team's jobs, focus a job.
  • Review — counts for a job; applicants bucketed into strong / possible / weak with the reason for each; everything about one candidate (profile, CV, skills, scores, the agent's assessment).
  • Search — your entire past-applicant pool, across every job, in plain language ("night-shift supervisor, drives, lives nearby").
  • Act — draft a job, approve (publish) it, pause / resume it, and email a candidate from your address.

Try asking

  • "On the Caretaker job, who are the strongest applicants and why?"
  • "Have we ever seen a Thai-speaking night-shift supervisor across any job?"
  • "Does Maria have any social-media experience?"
  • "Draft a job for a weekend barista, then show it to me before publishing."
  • "Write a warm note to Daniel asking if he can start next Monday."

A few guarantees

  • Creating a job only makes a draft — nothing goes live and no one is charged until you approve it.
  • The assistant never charges a card. If publishing needs payment, it hands you a checkout link to complete yourself.
  • It only touches hiring — never your billing, team membership, or account settings. Every action is scoped to the team you've selected, and the assistant tells you which team and job it's acting on.
  • Revoke access any time from your dashboard.

REST API

The intake API lets a partner front-end post jobs into BKKStaff and submit applications to them. BKKStaff stays the source of truth — a job you post here is the same job the AI screens, so the listing and the screening can't drift. Applications flow into the normal funnel (scoring → Recruiting Agent) exactly like a candidate who applied on BKKStaff directly.

Base URL & authentication

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

Every request is authenticated with a per-account API key, sent as a Bearer token (or an X-API-Key header). A key only ever touches its own account's jobs. Keys are issued on request — contact us to get one.

Authorization: Bearer YOUR_API_KEY

Draft a job from a raw ad

POST /jobs/draft

Send the raw text of an ad (plus an optional title, and the client's company and contact email). It's parsed into a structured draft — pending, not live. The company/email become the job's public identity so candidate emails come from the client, not BKKStaff.

curl -X POST https://app.bkkstaff.com/api/v1/jobs/draft \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Line Cook",
    "text": "Busy Kingston restaurant needs a line cook, nights & weekends...",
    "company": "Aunt Mertle'\''s Kitchen",
    "email": "[email protected]"
  }'

→ 201

{
  "slug": "j4821",
  "application_email": "[email protected]",
  "fields": { "title": "Line Cook", "summary": "...", "description": "...", ... }
}

Read a job

GET /jobs/:slug

The canonical job — render your public listing from this so it always matches what's being screened. Returns title, summary, description, category, work mode, employment type, salary fields, location, status, criteria_status, the identity overrides, the application_email, and whether it's currently accepting applications.

Update a job

PATCH /jobs/:slug  ·  PUT /jobs/:slug

Update a live job's content (title, summary, description, salary, location, identity). You can't flip status, plan, or payment. Editing the description of a job whose criteria are ready re-runs screening criteria, so the AI's rubric always re-aligns with what candidates now see.

Publish a job

POST /jobs/:slug/publish

Persist the assistant's edits and activate the job: screening criteria are generated and it starts accepting applications.

{ "slug": "j4821", "status": "active", "application_email": "[email protected]" }

Submit an application

POST /jobs/:slug/applications

Send a candidate as multipart/form-data so you can attach the CV file (field cv, optional — a cover note alone is accepted). Pass either first_name/last_name or a single 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" }

Accepted fields: name (or first_name + last_name), email, phone, country, timezone, cover_note, opted_in, and the cv file.

Responses & errors

Success is 200 or 201 with a JSON body. Errors are a JSON object {"error": "code"} with the matching HTTP status:

StatuserrorMeaning
401unauthorizedMissing or invalid API key
404not_foundNo such job for this account
409duplicateThis candidate already applied to this job
422not_acceptingJob is closed or at its applicant cap
422missing_name / invalid_email / missing_contentApplication failed validation
422could_not_parse_adThe ad text couldn't be turned into a draft
502cv_upload_failedThe CV file couldn't be stored — retry

Need an API key, a higher applicant cap, or help wiring this up? Reach us at [email protected].