Ashby
This page contains the setup guide and reference information for the Ashby source connector.
Prerequisites
- An Ashby account
- An Ashby API key with the appropriate permissions for the streams you want to sync. See the Ashby authentication docs for details on how to create an API key.
Your API key must have read permissions enabled for the modules that correspond to the streams you want to sync:
| Ashby permission module | Streams |
|---|---|
| Candidates | applications, application_criteria_evaluations, application_feedback, application_history, candidates |
| Interviews | interviews, interview_plans, interview_schedules, interview_stage_groups, interview_stages |
| Jobs | job_boards, job_postings, job_templates, jobs, openings |
| Hiring Process | archive_reasons, candidate_tags, custom_fields, feedback_form_definitions, interviewer_pools, source_tracking_links, sources, survey_form_definitions |
| Organization (always required) | departments, locations, users — The connection check validates connectivity using the users stream, so you must enable this permission even if you only intend to sync streams from other modules. Without it, the check fails with a 403 missing_endpoint_permission error. |
| Offers | offers |
| Approvals | approvals |
| Projects or Candidates | projects (Ashby accepts either permission) |
By default, Ashby API keys can't read confidential jobs and projects. To sync them, enable Allow access to confidential jobs and projects? on the API key.
The application_criteria_evaluations stream requires the AI Application Review feature to be enabled for your Ashby organization. If this feature is not enabled, the stream returns empty results.
Setup guide
- Log in to your Ashby account.
- Generate an API key following the Ashby authentication guide. Grant the API key read permissions for the modules listed in the prerequisites. At minimum, you must enable the Organization read permission (required for the connection check) plus read permissions for any additional modules whose streams you want to sync.
- In Airbyte, create a new Ashby source.
- Enter your API key.
- Enter a Start date in
YYYY-MM-DDTHH:MM:SSZformat. The connector sends this date as thecreatedAfterfilter on theapplication_feedback,applications, andinterview_schedulesstreams, so records created before it aren't replicated. The date also limitsapplication_criteria_evaluationsandapplication_history, because those streams read the same filtered application list to decide which applications to request child records for. All other streams ignore the start date and always return everything the API exposes.
Supported sync modes
| Feature | Supported |
|---|---|
| Full Refresh | Yes |
| Incremental - Append | Yes, for applications and application_history |
| Incremental - Append + Deduped | Yes, for applications and application_history |
Starting in version 1.5.0, the applications and application_history streams support incremental sync on the application's updatedAt timestamp. Every other stream re-reads in full on each sync, subject to the start date where it applies. Many Ashby .list endpoints support incremental sync through a syncToken, but this connector doesn't use it.
Ashby's application.list doesn't filter on updatedAt, so an incremental sync of applications still reads every application from Ashby and emits only those updated no earlier than 1 day before the latest updatedAt from the previous sync. The 1-day lookback exists because Ashby returns applications in creation order, so an application updated during a sync could otherwise be missed. Applications updated within that day are emitted again on the next sync, so use Incremental | Append + Deduped, keyed on id, to keep one row per application. Because every incremental sync still reads the full application list, the time savings come from application_history, described below. On existing connections, refresh the source schema to see the Incremental mode and the application_updated_at column on application_history.
Supported streams
This source syncs the following streams:
- applications
- application_criteria_evaluations (substream of applications)
- application_feedback
- application_history (substream of applications)
- approvals
- archive_reasons
- candidate_tags
- candidates
- custom_fields
- departments
- feedback_form_definitions
- interview_plans
- interview_schedules
- interview_stage_groups
- interviews
- interview_stages
- interviewer_pools
- job_boards
- job_postings
- job_templates
- jobs
- locations
- offers
- openings
- projects
- source_tracking_links
- sources
- survey_form_definitions
- users
The application_criteria_evaluations stream is a substream of applications. The connector requests evaluations only for applications whose current interview stage has the type PreInterviewScreen and whose status is neither Archived nor Hired, so it doesn't cover every application in your account. Each record carries an application_id field copied from the parent application, which is how you join evaluations back to applications. This stream has no primary key. Starting in version 1.4.0, the connector pages through every evaluation for each application. Earlier versions synced only the first page. Like application_history, this stream makes at least one request per application, so the connector caps application.listCriteriaEvaluations at 100 requests per minute and skips applications for which Ashby returns application_not_found.
The application_history stream is a substream of applications. Each record is one interview stage an application entered, with the enteredStageAt and leftStageAt timestamps that no other Ashby endpoint exposes. Join application_history.application_id to applications.id and application_history.stageId to interview_stages.id. Along with application_id, the connector copies the parent application's status, creation timestamp, and update timestamp into each record as application_status, application_created_at, and application_updated_at, so you can analyze stage timing without joining back to applications. The stream has a primary key of id, so deduplicating destinations key history events instead of appending a copy on every sync.
The parent application list uses the same createdAfter filter as the applications stream. A start date later than your oldest application returns partial history rather than an error.
The connector requests history one application at a time, and application.listHistory accepts neither a date filter nor a syncToken. The connector caps this endpoint at 100 requests per minute, which puts a floor on how long a full sync can take: 10,000 applications need at least 100 minutes, and applications with more than 100 history records need additional requests to paginate.
In incremental mode, the first sync requests history for every application. Later syncs request history only for applications updated no earlier than 1 day before the latest updatedAt from the previous sync, so applications updated during the previous sync aren't missed. In testing, Ashby updated updatedAt when an application moved to a new stage, so new stage entries are picked up. Ashby doesn't update updatedAt for every change, for example edits or deletions of history entries made through application.updateHistory and some application changes, so run a periodic Refresh and remove records if those matter. Each changed application re-emits its full history, so use Incremental | Append + Deduped, keyed on id, to keep one row per history event. Incremental | Append adds a copy of the history each time. Each incremental sync still reads the full application list to find the changed applications. In full refresh mode, every sync re-reads the history of every selected application, so sync it on its own connection with an infrequent schedule.
If Ashby returns an application_not_found error for an application, which happens when the application is deleted or your API key can't access it, the connector skips that application's history, logs the Ashby request ID, and continues. It retries HTTP 429 and 5xx responses. Any other error fails the sync.
The application_feedback stream returns submitted interview scorecards, one record per feedback form submission, with the submittedValues an interviewer entered and the formDefinition that was in effect when the form was submitted. Join applicationId to applications.id, interviewId to interviews.id, and feedbackFormDefinitionId to feedback_form_definitions.id. submittedValues is a free-form object keyed by each field's path, so the connector doesn't declare its keys. For select fields, it holds the stored option value, such as hire, rather than the display label, such as Hire. To get labels, map each value through formDefinition.sections[].fields[].field.selectableValues on the same record, not through the current feedback_form_definitions stream, because a form definition can change after feedback is submitted. The creditedToUser field was added to the Ashby API on 2026-07-21 and may be null on older records. This endpoint requires the Candidates read permission.
The interview_stages stream is a substream of Ashby's interview plans. Ashby's interviewStage.list endpoint returns stages for one interview plan at a time, so starting in version 1.4.0 the connector lists your interview plans, including archived ones, and then requests the stages of each plan. Versions before 1.4.0 didn't send an interview plan ID and synced no stages. Each record carries interviewPlanId and an interview_plan_is_archived flag copied from the parent plan. Join interviewPlanId to interview_plans.id and interviewStageGroupId to interview_stage_groups.id. Ashby's interviewPlan.list doesn't return draft plans, and it returns job-specific plans only when your API key can read the associated job, so grant the Jobs read permission if you need job-specific plans in interview_plans or their stages in interview_stages.
The interviews stream returns interview definitions, which are the interview types configured in your Ashby account, such as a technical phone screen. It doesn't return scheduled interviews. Each record carries the definition's title, externalTitle, instructions, feedback settings, and feedbackFormDefinitionId. For interviews that were actually scheduled, along with their times and interviewers, use interview_schedules.
Starting in version 1.2.0, the connector sends includeNonSharedInterviews: true, so definitions that belong to a single job sync alongside shared ones. Use jobId to tell them apart: it holds the job the definition belongs to, and is null for shared definitions, which can be scheduled against any job. Starting in version 1.4.0, the connector also sends includeArchived: true, so archived definitions sync too. Use isArchived to filter them out.
Version 1.2.0 also declared the fields interview.list returns, which the schema previously omitted. Refresh the source schema and enable the new columns in your connection to replicate them. The stream keeps declaring twelve fields that describe a scheduled interview rather than a definition: applicationId, interviewScheduleId, interviewStageId, status, createdAt, updatedAt, cancelledAt, startTime, endTime, interviewerUserIds, meetingLink, and feedbackLink. Ashby's interview.list endpoint doesn't return them, so those columns are always null. They stay in the schema so that removing them can be released as a breaking change later.
The openings stream returns headcount openings. Each record's latestVersion object holds the opening's current details, including jobIds and locationIds, which join to jobs.id and locations.id.
The approvals stream returns approval processes for offers, jobs, and openings. The connector doesn't filter by entity, so every approval in your organization syncs. Use entityType to tell which kind of record entityId refers to, then join entityId to offers.id, jobs.id, or openings.id.
Archived and deactivated records
Starting in version 1.4.0, the connector asks Ashby to include archived records for archive_reasons, candidate_tags, custom_fields, departments, feedback_form_definitions, interviews, locations, and sources, and deactivated users for users. Earlier versions synced only active records from these streams, so your first sync after upgrading can return more rows. Filter on isArchived, or on isEnabled for users, if you only want active records.
The streams added in version 1.6.0 also include inactive records. interview_plans includes archived plans, and interviewer_pools includes archived pools and archived training stages. Filter on isArchived to exclude them. source_tracking_links includes disabled links, so filter on enabled to exclude them.
Of the streams added in version 1.7.0, job_templates returns both active and inactive templates, so filter on status if you only want active ones. Ashby's jobBoard.list returns only enabled job boards, so job_boards doesn't include disabled ones.
Performance considerations
Ashby documents a rate limit of 1,000 requests per minute per API key. The connector reads up to two streams at a time. An API key shared with other integrations has less headroom, so to protect it, the connector limits itself to 100 requests per minute against each of application.listHistory and application.listCriteriaEvaluations, the endpoints it calls at least once per application. The connector applies no request budget to any other endpoint. If Ashby responds with HTTP 429, the connector waits for the Retry-After interval, or backs off exponentially if the header is missing, and retries.
Troubleshooting
Ashby reports most errors as HTTP 200 responses with success: false in the body. Starting in version 1.4.0, the connector fails the sync on these responses and includes Ashby's error code, message, and request ID in the error. Earlier versions could finish a sync without records and without reporting an error.
- HTTP 401 Unauthorized: Ashby rejected the API key. Check that the key in the source settings is correct and still active, or generate a new key in Ashby.
- HTTP 403 Forbidden: The API key may be deactivated or lack access. Generate a new key in Ashby.
missing_endpoint_permission: The API key lacks the read permission a selected stream needs. The error message names the missing permission. Enable it on the key, using the permission table, or deselect the stream.
The connector retries HTTP 429 and 5xx responses before failing.
IP allow list
If you use Airbyte Cloud and your organization restricts access to specific IPs, add the Airbyte Cloud IP addresses to your allow list.
Upgrading to 1.0.0
Version 1.0.0 declares element schemas for array columns that the connector previously left untyped. On data-lake destinations such as S3 Data Lake and Iceberg, those columns change type, so syncs can fail with a schema evolution error. Refresh the affected streams first, and drop and recreate the affected destination tables only if a sync still fails. For the full list of affected columns and the upgrade steps, see the Ashby migration guide.
Reference
Config fields reference
Changelog
Expand to review
| Version | Date | Pull Request | Subject |
|---|---|---|---|
| 1.7.1 | 2026-10-06 | 87745 | Update dependencies |
| 1.7.0 | 2026-10-05 | 87590 | Add openings, job templates, job boards, approvals, and projects streams |
| 1.6.0 | 2026-10-05 | 87587 | Add interview plans, interview stage groups, interviewer pools, survey form definitions, and source tracking links streams |
| 1.5.0 | 2026-10-02 | 87597 | Add incremental sync to applications and application_history, so incremental syncs request history only for applications updated since the previous sync, with a 1-day lookback |
| 1.4.0 | 2026-09-30 | 87051 | Fail syncs on Ashby success: false errors, sync interview_stages per interview plan, paginate application_criteria_evaluations, and include archived and deactivated records in lookup streams |
| 1.3.4 | 2026-09-29 | 87080 | Update dependencies |
| 1.3.3 | 2026-09-22 | 86515 | Update dependencies |
| 1.3.2 | 2026-09-21 | 86501 | chore(source-ashby): wire sandbox acceptance-test secret, mark offers/interview_stages empty, add mock server tests |
| 1.3.1 | 2026-09-15 | 85974 | Update dependencies |
| 1.3.0 | 2026-09-09 | 85755 | Add application_feedback stream; send the API key as the Basic auth username with a blank password per Ashby docs |
| 1.2.1 | 2026-09-08 | 85402 | Update dependencies |
| 1.2.0 | 2026-08-29 | 85183 | Declare the interview definition fields interview.list actually returns on the interviews stream, and request non-shared (job-specific) interviews |
| 1.1.0 | 2026-08-25 | 84392 | Add application history stream |
| 1.0.1 | 2026-08-25 | 84405 | Send the pagination page size using Ashby's documented limit field instead of the undocumented per_page field |
| 1.0.0 | 2026-08-18 | 84274 | Breaking: declare documented API fields across stream schemas, including element schemas for previously untyped array columns. Data-lake users must refresh the affected streams, then recreate the affected tables if a sync still fails. See the migration guide. |
| 0.3.9 | 2026-08-18 | 78554 | Update dependencies |
| 0.3.8 | 2026-08-11 | 84215 | Promoted release candidate to GA |
| 0.3.8-rc.5 | 2026-08-11 | 84214 | Revert the concurrency work from 0.3.8-rc.1 through 0.3.8-rc.3: remove the API budget, concurrency level, and num_workers option. |
| 0.3.8-rc.4 | 2026-08-11 | 83816 | Add missing application, candidate, and source fields to the declared schemas, and remove duplicated unreferenced manifest blocks. |
| 0.3.8-rc.3 | 2026-05-26 | 78434 | Decrease default concurrency to 2 and add explicit worker count plus API request budget for the next rollout. |
| 0.3.8-rc.2 | 2026-05-21 | 78307 | Decrease default concurrency to 3 after Phase 1 rollout monitoring found source-read regressions and a 429 retry warning. |
| 0.3.8-rc.1 | 2026-05-18 | 77048 | Add concurrency support with default_concurrency=4 for concurrent stream reads |
| 0.3.7 | 2026-04-28 | 77144 | Update dependencies |
| 0.3.6 | 2026-04-21 | 76510 | Update dependencies |
| 0.3.5 | 2026-03-31 | 75881 | Update dependencies |
| 0.3.4 | 2026-03-24 | 75325 | Update dependencies |
| 0.3.3 | 2026-03-10 | 74490 | Update dependencies |
| 0.3.2 | 2026-02-24 | 73805 | Update dependencies |
| 0.3.1 | 2026-02-17 | 60692 | Update dependencies |
| 0.3.0 | 2026-02-13 | 73244 | Add interviews, interview_stages, and application_criteria_evaluations streams |
| 0.2.23 | 2025-05-10 | 59853 | Update dependencies |
| 0.2.22 | 2025-05-03 | 59322 | Update dependencies |
| 0.2.21 | 2025-04-26 | 58746 | Update dependencies |
| 0.2.20 | 2025-04-19 | 58271 | Update dependencies |
| 0.2.19 | 2025-04-12 | 57150 | Update dependencies |
| 0.2.18 | 2025-03-29 | 56594 | Update dependencies |
| 0.2.17 | 2025-03-22 | 56140 | Update dependencies |
| 0.2.16 | 2025-03-08 | 55387 | Update dependencies |
| 0.2.15 | 2025-03-01 | 54888 | Update dependencies |
| 0.2.14 | 2025-02-22 | 54234 | Update dependencies |
| 0.2.13 | 2025-02-15 | 53874 | Update dependencies |
| 0.2.12 | 2025-02-08 | 53407 | Update dependencies |
| 0.2.11 | 2025-02-01 | 52893 | Update dependencies |
| 0.2.10 | 2025-01-25 | 52162 | Update dependencies |
| 0.2.9 | 2025-01-18 | 51710 | Update dependencies |
| 0.2.8 | 2025-01-11 | 51292 | Update dependencies |
| 0.2.7 | 2024-12-28 | 50493 | Update dependencies |
| 0.2.6 | 2024-12-21 | 50207 | Update dependencies |
| 0.2.5 | 2024-12-14 | 49572 | Update dependencies |
| 0.2.4 | 2024-12-12 | 49014 | Update dependencies |
| 0.2.3 | 2024-11-04 | 48196 | Update dependencies |
| 0.2.2 | 2024-10-29 | 47729 | Update dependencies |
| 0.2.1 | 2024-10-28 | 47616 | Update dependencies |
| 0.2.0 | 2024-08-19 | 44420 | Refactor connector to manifest-only format |
| 0.1.16 | 2024-08-17 | 44288 | Update dependencies |
| 0.1.15 | 2024-08-12 | 43780 | Update dependencies |
| 0.1.14 | 2024-08-10 | 43491 | Update dependencies |
| 0.1.13 | 2024-08-03 | 43080 | Update dependencies |
| 0.1.12 | 2024-07-27 | 42658 | Update dependencies |
| 0.1.11 | 2024-07-20 | 42220 | Update dependencies |
| 0.1.10 | 2024-07-17 | 42028 | Fix typo in application stream |
| 0.1.9 | 2024-07-13 | 41818 | Update dependencies |
| 0.1.8 | 2024-07-10 | 41379 | Update dependencies |
| 0.1.7 | 2024-07-09 | 41271 | Update dependencies |
| 0.1.6 | 2024-07-06 | 40971 | Update dependencies |
| 0.1.5 | 2024-06-25 | 40469 | Update dependencies |
| 0.1.4 | 2024-06-22 | 40107 | Update dependencies |
| 0.1.3 | 2024-06-06 | 39159 | [autopull] Upgrade base image to v1.2.2 |
| 0.1.2 | 2024-05-28 | 38666 | Make connector compatible with Builder |
| 0.1.1 | 2024-05-20 | 38421 | [autopull] base image + poetry + up_to_date |
| 0.1.0 | 2022-10-22 | 18334 | Add Ashby Source Connector |