| name | Ashby API Guide |
| description | 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. |
| version | 0.1.0 |
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="jane@example.com")
# By name (partial match)
candidate_search(name="Jane")
Create and Apply Candidate
# Step 1: Create candidate
candidate = candidate_create(
name="Jane Smith",
email="jane@example.com"
)
# 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