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:
| Status | error | Meaning |
|---|---|---|
| 401 | unauthorized | Missing or invalid API key |
| 404 | not_found | No such job for this account |
| 409 | duplicate | This candidate already applied to this job |
| 422 | not_accepting | Job is closed or at its applicant cap |
| 422 | missing_name / invalid_email / missing_content | Application failed validation |
| 422 | could_not_parse_ad | The ad text couldn't be turned into a draft |
| 502 | cv_upload_failed | The 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].