For employers
One endpoint, a bearer key, and the same checks the web form runs.
Sign in at bolthiring.com/employers, fill in your company details, and once the company is verified the Company tab has a Post from your own system panel. Name a key, create it, and copy it there and then.
We store a hash and the first sixteen characters, nothing else. The key cannot be shown to you again, by us or by anyone who reaches our database. If it is lost, revoke it and make another.
Verification comes first because a key posts with nobody at the keyboard. Five live keys per company; revoking one stops it immediately.
POST https://bolthiring.com/api/v1/jobs
Authorization: Bearer bh_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"title": "Java Engineer",
"location": "Charlotte, NC",
"roles": ["Java Developer"],
"skills": ["Java", "Spring Boot", "AWS"],
"arrangement": "Onsite",
"employment_type": "C2C",
"pay": "$60-70/hr",
"contact_email": "recruiting@yourcompany.com",
"work_auth": ["USC", "GC", "H1B", "OPT"],
"hiring_for": "client_via_vendor",
"description": "What the work is. Plain text, up to 6000 characters."
}
A successful call returns the posting and where it went:
200 OK
{
"ok": true,
"id": "6f1c…",
"slug": "java-engineer-charlotte-nc-a1b2c3",
"url": "https://bolthiring.com/jobs/java-engineer-charlotte-nc-a1b2c3",
"approved": true,
"status": "live",
"flagged": 0,
"message": "Live. It is on the site now and on its way to matching job seekers."
}
status is live or awaiting_review. A live posting is on
the site and its alerts have already gone out.
The response also echoes the roles and location we stored, and lists
anything we worked out for you in derived. Titles carry a grade and a qualifier that
our list does not, so Senior Java Developer becomes Java Developer,
Apache Kafka becomes Kafka, and Remote becomes
Remote (US). Check derived if you want to know when we guessed.
| Field | Required | Notes |
|---|---|---|
title | yes | Up to 160 characters. |
location | yes | One place. We resolve common forms, so Remote, NYC, Plano, TX and Charlotte all land correctly. If it does not resolve the response says what you sent. |
roles | usually | Array, up to 2. This is what job seekers filter on. Send an empty array and we derive one from the title: GPC Platform Architect becomes Solution Architect. The response tells you what we used. |
skills | no | Array, up to 6, from the skills list. |
description | no | Plain text, up to 6000 characters. Behind the gate; a redacted snippet shows publicly. |
contact_email | no | Where candidates write. Behind the gate. |
pay | no | Free text, for example $60-70/hr. Behind the gate. |
arrangement | no | Onsite, Hybrid or Remote. |
employment_type | no | C2C, W2, Full-time or Contract to hire. |
work_auth | no | Array from USC, GC, H1B, OPT. All four displays as Any. State who you accept, never who you exclude. |
hiring_for | no | own_team, client or client_via_vendor. |
acknowledged | no | Set true to post despite flagged wording. See errors. |
rebuild_slug | no | PATCH only. Rebuild the URL from the new title. The old one redirects to it. |
Anything not listed is ignored. Values outside the lists are dropped rather than guessed at, so check the response rather than assuming a field landed.
PATCH https://bolthiring.com/api/v1/jobs
Authorization: Bearer bh_live_...
Content-Type: application/json
{ "id": "6f1c…", "pay": "$70-80/hr", "contact_email": "newrecruiter@yourcompany.com" }
Send the whole posting, not just what changed: fields you leave out are cleared, the same as
the create call. The id comes from the create response or from GET.
The slug is built once from the title, so correcting a title leaves the old spelling in the
URL. Send "rebuild_slug": true to rebuild it. The old address keeps working and
redirects permanently to the new one, so a link already shared still arrives. The response says
slug_changed when it did.
The id and the slug survive, so a link already shared keeps working, and nobody is emailed again. The alerts went out when the role was created and a correction is not news.
The wording screen runs on the new text. An edit whose wording trips a high flag drops the
posting back to awaiting_review and off the site until a person has read it, however
long it had been live. Otherwise editing would be the way around a check the original had to pass.
GET https://bolthiring.com/api/v1/jobs Authorization: Bearer bh_live_...
Returns your postings from the last 60 days, each with a status of
live, awaiting_review or filled. Use it to reconcile what
your system sent against what is actually up, rather than scraping the site.
GET https://bolthiring.com/api/v1/taxonomy
Public, no key needed. Returns every location, role and skill we accept, the work authorization and hiring-for values, and the aliases we resolve.
Aliases mean you usually do not have to normalise: Apache Kafka resolves to
Kafka, Golang to Go, PL/SQL to
Oracle. Vendor prefixes are stripped generally, so Apache Cassandra
resolves to Cassandra with no alias needed.
| Code | Means |
|---|---|
401 | Key missing, malformed, or revoked. |
403 | Company details incomplete, or the account is paused. |
400 | A field is missing or not from the list. The response names it in field. |
429 | Past the hourly limit. Retry-After says when. |
502 | We could not save it. Safe to retry. |
One 400 is worth handling on its own. Wording that reads as an age screen, a citizenship exclusion, a demand for identity documents or a protected characteristic comes back flagged and unposted:
400 Bad Request
{
"error": "Wording on this posting needs a look before it can go out.",
"flags": [
{ "category": "Work authorization", "text": "No GC",
"level": "high",
"why": "Excluding people by immigration status is citizenship-status discrimination under 8 U.S.C. §1324b…" }
]
}
Fix the wording and post again, or send "acknowledged": true to post it anyway.
Acknowledging sends the posting for review rather than publishing it, and what was flagged is
stored with it.
120 postings an hour per company, counted across every key, so more keys does not buy more room.
Retries are safe. The same title and location from the same company within ten minutes
returns the posting already made, marked "duplicate": true, rather than creating a
second. A timed-out request that actually succeeded will not become two openings.
Your first posting is read by a person. After one has passed, a verified company publishes straight through and the alerts fire immediately. Wording flagged as high severity goes back to review whatever your history.
Postings expire after 30 days and come off the site and out of the digest. Mark one filled sooner from the dashboard.
Questions, or something behaving oddly: info@bolthiring.com.