- TypeScript 100%
job-posting sync recorded every unpublished (Draft) posting as status: not_found and overwrote its stored state, even with includeUnpublishedJobPostings: true on the model. sync called jobPosting.info with only the stored id, and Ashby hides unpublished postings from that read unless the flag is sent. update already sent it, so update worked on a Draft and sync did not. offer sync had the same gap with excludeFormDefinition. - sync now also sends each global argument that the read endpoint accepts (jobPosting: includeUnpublishedJobPostings; offer: excludeFormDefinition), only when it is set - global arguments that only create or only update accepts now say so in their description, e.g. jobPosting's applicationConfirmationEmailTemplateId, which jobPosting.create does not accept - generated test: sync sends a configured read parameter and omits it when unset; verified to fail against 2026.10.29.1 - codegen versions per model like the official generators: only the 10 models whose output changed move to 2026.10.29.2, each with an upgrades entry; the six affected packages move to 2026.10.29.2 and surveys is unchanged Reported by @mahirl. Fixes #1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| candidates | ||
| codegen | ||
| interviews | ||
| jobs | ||
| offers | ||
| organization | ||
| sourcing | ||
| spec | ||
| surveys | ||
| .gitignore | ||
| .swamp.yaml | ||
| CLAUDE.md | ||
| deno.json | ||
| deno.lock | ||
| LICENSE.txt | ||
| README.md | ||
swamp-ashby
swamp extensions for the Ashby ATS API, generated from Ashby's OpenAPI spec. Every client-callable Ashby endpoint (201 of them) is covered, split into seven extensions by area:
| Extension | Covers |
|---|---|
@keeb/ashby/candidates |
candidates, tags, applications and their history, application feedback, application forms, referrals, assessments, file uploads |
@keeb/ashby/jobs |
jobs, job postings, openings, locations, departments, hiring teams, approvals, job boards, job templates |
@keeb/ashby/interviews |
interviews, interview plans and stages, schedules and events, briefings, interviewer pools, feedback forms, take-home assignments, notetaker transcripts |
@keeb/ashby/offers |
offer processes, offers, offer approvals and decisions |
@keeb/ashby/sourcing |
projects, sequences and sequence templates, sources and tracking links, email senders, the email sync blocklist, communication templates, archive reasons |
@keeb/ashby/surveys |
survey form definitions, requests and submissions |
@keeb/ashby/organization |
users and interviewer settings, brands, custom fields, webhooks, reports, the audit log, API key info, API versions |
Each Ashby resource is one model, @keeb/ashby/<extension>/<resource>, with
the standard swamp method set where the resource supports it — create,
get, lookup, update, delete, sync — and a snake_case action for
every other endpoint (candidate.addTag → add_tag). Each extension's README
lists its models and methods.
swamp extension pull @keeb/ashby/jobs
swamp model create @keeb/ashby/jobs/job ashby-job \
--global-arg 'apiKey=${{ vault.get("default", "ASHBY_API_KEY") }}'
swamp model method run ashby-job lookup
Layout
codegen/
fetch-spec.ts refresh spec/ashby-openapi.json from Ashby's docs
generate.ts write every package from the spec
lib/ashby.ts the shared HTTP helper, copied into each package's _lib/
endpoints.json generated map of every endpoint to its model and method
spec/ Ashby's OpenAPI spec, merged from the reference pages
<extension>/ one generated package per extension (do not edit)
Regenerating
deno task fetch-spec # pick up Ashby API changes
deno task generate # rewrite every package
deno task test # lib, per-model, and coverage tests
generate.ts asserts the registry's listing limits (50 models per
extension, 50 methods per model, 30 arguments per method or model) and writes
every listed field literally in each model file, so a package that would
publish without a listing fails to generate instead. codegen/coverage_test.ts
checks every client-callable endpoint is wrapped exactly once.
Not wrapped: the four endpoints Ashby calls on assessment partners
(assessment.start, assessment.list, assessment.cancel,
customFields.fetch) and the deprecated aliases application.change_stage /
application.change_source.
Publishing
for d in candidates jobs interviews offers sourcing surveys organization; do
(cd "$d" && swamp extension push manifest.yaml --yes)
done
License
MIT — see LICENSE.txt.