Ashby API Guide
ashby-api-guide
This skill should be used when the user asks about "Ashby API", "how to use Ashby tools", "Ashby authentication", "Ashby MCP tools", "what can I do with Ashby", or needs help understanding available Ashby operations. Provides complete API documentation and tool usage guidance.
SKILL.md
Full skill instructions
Ashby API Guide
Reference guide for working with the Ashby ATS integration. This skill covers authentication, available tools, and common usage patterns.
Overview
The Ashby plugin provides ~30 MCP tools for interacting with Ashby's Applicant Tracking System (ATS). All operations use Ashby's RPC-style API where every endpoint accepts POST requests.
Authentication
Ashby uses Basic Authentication with an API key:
- Generate an API key in Ashby: Settings → API Keys
- Set the environment variable:
ASHBY_API_KEY=your-api-key - The MCP server handles authentication automatically
API keys have permission scopes. Common permissions needed:
candidatesRead/candidatesWrite- Candidate operationsjobsRead/jobsWrite- Job operationsinterviewsWrite- Interview scheduling
Available Tools
Candidate Management
| Tool | Purpose | Required Params |
|---|---|---|
candidate_create | Create new candidate | name, email |
candidate_search | Find by email/name | email or name |
candidate_list | List all candidates | (optional) cursor, limit |
candidate_info | Get candidate details | candidateId |
candidate_update | Update candidate | candidateId |
candidate_add_note | Add note to profile | candidateId, note |
candidate_add_tag | Tag a candidate | candidateId, tagId |
candidate_list_notes | View all notes | candidateId |
Job Management
| Tool | Purpose | Required Params |
|---|---|---|
job_create | Create new job | title |
job_search | Find jobs | (optional) title, status |
job_list | List all jobs | (optional) cursor, limit |
job_info | Get job details | jobId |
job_set_status | Update status | jobId, status |
Job statuses: Open, Closed, Draft, Archived
Application Management
| Tool | Purpose | Required Params |
|---|---|---|
application_create | Consider candidate for job | candidateId, jobId |
application_list | List applications | (optional) jobId, candidateId, status |
application_info | Get application details | applicationId |
application_change_stage | Move in pipeline | applicationId, interviewStageId |
application_change_source | Update attribution | applicationId, sourceId |
application_update | Update properties | applicationId |
Application statuses: Active, Hired, Archived
Interview Scheduling
| Tool | Purpose | Required Params |
|---|---|---|
interview_list | List interviews | (optional) applicationId |
interview_schedule_create | Schedule interview | applicationId, interviewerUserIds, startTime, endTime |
interview_schedule_list | List schedules | (optional) startTimeAfter, startTimeBefore |
interview_schedule_update | Modify schedule | interviewScheduleId |
interview_schedule_cancel | Cancel interview | interviewScheduleId |
Organization
| Tool | Purpose | Required Params |
|---|---|---|
user_list | List team members | (optional) includeDeactivated |
user_search | Find user | email or name |
department_list | List departments | (optional) includeArchived |
location_list | List locations | (optional) includeArchived |
Offers
| Tool | Purpose | Required Params |
|---|---|---|
offer_create | Create offer | applicationId |
offer_list | List offers | (optional) applicationId |
Utilities
| Tool | Purpose | Required Params |
|---|---|---|
interview_stage_list | Get pipeline stages | (optional) jobId |
source_list | Get candidate sources | (optional) cursor |
candidate_tag_list | Get available tags | (optional) cursor |
archive_reason_list | Get rejection reasons | none |
Common Operations
Find a Candidate
# By email (exact match)
candidate_search(email="[email protected]")
# By name (partial match)
candidate_search(name="Jane")
Create and Apply Candidate
# Step 1: Create candidate
candidate = candidate_create(
name="Jane Smith",
email="[email protected]"
)
# Step 2: Apply to job
application_create(
candidateId=candidate["id"],
jobId="target-job-id"
)
Move Candidate Through Pipeline
# Get current stage and next stage
stages = interview_stage_list(jobId="...")
next_stage_id = stages["results"][1]["id"]
# Move application
application_change_stage(
applicationId="app-id",
interviewStageId=next_stage_id
)
Schedule an Interview
interview_schedule_create(
applicationId="app-id",
interviewerUserIds=["user-1", "user-2"],
startTime="2024-01-15T14:00:00Z",
endTime="2024-01-15T15:00:00Z"
)
Reject a Candidate
# Get archive reasons
reasons = archive_reason_list()
reason_id = reasons["results"][0]["id"] # e.g., "Not qualified"
# Get archived stage
stages = interview_stage_list(jobId="...")
archived_stage = next(s for s in stages["results"] if s["type"] == "Archived")
# Archive
application_change_stage(
applicationId="app-id",
interviewStageId=archived_stage["id"],
archiveReasonId=reason_id
)
Response Format
All tools return JSON. Successful responses have this structure:
{
"success": true,
"results": { ... } // or array for list operations
}
List operations include pagination:
{
"success": true,
"results": [...],
"moreDataAvailable": true,
"nextCursor": "cursor-string"
}
Error responses:
{
"success": false,
"errors": ["error_code"]
}
Pagination
List operations use cursor-based pagination:
# First page
results = candidate_list(limit=50)
# Next page (if moreDataAvailable is true)
results = candidate_list(limit=50, cursor=results["nextCursor"])
Date/Time Format
All timestamps use ISO 8601 format:
2024-01-15T14:00:00Z(UTC)2024-01-15T14:00:00-08:00(with offset)
Error Codes
Common error codes and meanings:
| Code | Meaning |
|---|---|
invalid_input | Missing or malformed parameter |
not_found | Resource doesn't exist |
unauthorized | Permission denied |
rate_limited | Too many requests |
already_exists | Duplicate entry |
Tips
Finding IDs
Most operations require resource IDs. Use search/list tools first:
# Get candidate ID
candidate = candidate_search(email="...")["results"][0]
candidate_id = candidate["id"]
# Get job ID
job = job_search(title="...")["results"][0]
job_id = job["id"]
Filtering Applications
Filter by multiple criteria:
# All active apps for a specific job
application_list(jobId="...", status="Active")
# All apps for a specific candidate
application_list(candidateId="...")
Source Attribution
Always track where candidates come from:
# Get available sources
sources = source_list()
# Apply with source
application_create(
candidateId="...",
jobId="...",
sourceId="linkedin-source-id"
)
Additional Resources
Reference Files
For complete API patterns:
references/tool-reference.md- Full parameter details for all tools
Related Skills
- ashby-workflows - Pipeline management and recruiting workflows
