Ashby
Post a job to Ashby: title, team, location, employment type, interview plan, template and brand. BYOK-only, production writes.
Use Ashby to stand up a role directly in the customer's ATS: create a job with its team, location and
employment type, open it, and publish the candidate-facing posting. Hyreflow reads only the department
list, to resolve a teamId and verify the key.
Free (BYOK). Ashby writes cost no credits. Connect your own Ashby API key from the dashboard
Integrations page. The key needs Ashby's jobsWrite permission, granted per module under the
API-key settings in Ashby — without it the call comes back 403 missing_endpoint_permission. list_departments is the free connection check: it verifies the key and returns the departments a teamId comes from.
Capability
| Tool | Does | Cost |
|---|---|---|
create_job | Create a job in Draft status | Free |
set_job_status | Move a job between Draft, Open, Closed and Archived | Free |
create_job_posting | Create (and optionally publish) the candidate-facing posting | Free |
create_job parameters
Ashby's schema is closed — any field not in this table is rejected outright.
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | yes | The job title. |
teamId | UUID | yes | The department/team the job belongs to. |
locationId | UUID | yes | The job's location. |
defaultInterviewPlanId | UUID | no | A job cannot be opened without one; omitting it here just defers setting it. |
jobTemplateId | UUID | no | Only an active template may be used. |
employmentType | string | no | One of FullTime, PartTime, Intern, Contract, Temporary. |
brandId | UUID | no | The brand the job publishes under. |
teamId, locationId, defaultInterviewPlanId, jobTemplateId and brandId are Ashby UUIDs. list_departments returns the teamId values; the rest Hyreflow does not look up, so
ask the user for them, or have them read the ids out of
Ashby's admin URLs (Departments, Locations, Job Templates, Brands). Never guess a UUID — a wrong id is a
failed write, and Ashby doesn't say which field was wrong.
hyreflow tools execute ashby_create_job --payload '{
"title": "Senior Platform Engineer",
"teamId": "f9e52a51-a075-4116-a7b8-484deba69004",
"locationId": "3ae2b801-19f6-41ef-ad28-214bd731948f",
"employmentType": "FullTime"
}'The response is {success, results}; the new job's id is results.id.
Ashby answers a rejected write with HTTP 200 and success: false. Hyreflow turns that into an
error rather than a fake success — treat any error text as "the job was not created", and check Ashby
before retrying a timed-out call. There is no idempotency key, so a blind retry can create a duplicate.
set_job_status parameters
| Field | Type | Required | Notes |
|---|---|---|---|
job_id | UUID | yes | The job to move. |
status | string | yes | Draft, Open, Closed or Archived. |
close_reason_id | UUID | only with Closed | Accepted only alongside Closed. |
A job can't move to Open until it has a default interview plan — set defaultInterviewPlanId at
create time or the open fails.
hyreflow tools execute ashby_set_job_status --payload '{
"job_id": "1be42b8e-cafd-4beb-8121-f4981eb20f42",
"status": "Open"
}'create_job_posting parameters
This is the call that puts a role on a careers page — Ashby models the posting as a separate object from
the job, so create_job alone publishes nothing.
| Field | Type | Required | Notes |
|---|---|---|---|
jobId | UUID | yes | The job the posting belongs to. |
title | string | no | Defaults to the parent job's title. |
description | object | required to publish | {"type": "text/html", "value": "<p>…</p>"}. |
status | string | no | Draft (default) or Published. |
workplaceType | string | no | OnSite, Hybrid, Remote. |
isListed | boolean | no | Defaults to true; forced false when the parent job is confidential. |
locationId | UUID | no | Inherits the job's location. |
secondaryLocationIds | array of UUID | no | Additional locations. |
applicationFormDefinitionId | UUID | no | Falls back to the org's default form. |
The posting defaults to Draft — pass "status": "Published" to go live, and a published posting must
carry a description.
hyreflow tools execute ashby_create_job_posting --payload '{
"jobId": "1be42b8e-cafd-4beb-8121-f4981eb20f42",
"description": {"type": "text/html", "value": "<p>Own the deployment platform.</p>"},
"status": "Published",
"workplaceType": "Hybrid"
}'Publishing is public and irreversible in the way that matters — candidates can see it. Confirm with the
user before the Published call, not after.
What creating a job does not do
- The job is created in
Draft. Opening it isset_job_status, above, and it can't be opened at all until it has a default interview plan. - Nothing appears on a careers page yet. Ashby models the candidate-facing posting as a separate
object from the job;
create_job_posting, above, creates and optionally publishes it. confidentialcannot be set through the API, on create or update.
This is a write into the customer's own ATS. Confirm the exact payload — title, team, location, employment type — with the user before executing.