Endpoint
Sync jobs
Push every new JD from your ATS or careers page into Astris the moment it's published. One job at a time, or up to 100 in a batch.
Authentication
Requires the jobs scope. Key must be employer-scoped.
Endpoints
POST
/api/v1/jobs/syncPOST
/api/v1/jobs/bulk-syncGET
/api/v1/jobsPOST /api/v1/jobs/sync — request
Provide either text (Astris parses it) or parsed (you already have structured JD data).
textstringThe raw JD body. Astris parses it via the same pipeline used by the UI (Sonnet 4.6 + vision fallback for scanned PDFs).
parsedParsedJobDescriptionPre-parsed JD. Skips the parser entirely.
externalIdstringStable identifier from your system. When you re-POST with the same
externalId, Astris updates the existing job (idempotent sync).titlestringOverride the parsed title.
locationstringFallback "City, ST" if the parser didn't pick up location.
Response
{
"jobId": "c4fcc511-612c-40d2-bfc5-4bbb79e04312",
"slug": "apartment-maintenance-tech-c4fcc5",
"action": "created", // or "updated"
"parsed": {
"title": "Apartment Maintenance Tech",
"requiredCertifications": ["EPA Section 608"],
"hourlyMinUsd": 26,
"hourlyMaxUsd": 32,
"city": "Newark",
"state": "NJ"
}
}Example — cron-driven nightly sync (Node.js)
import "dotenv/config";
const KEY = process.env.ASTRIS_API_KEY;
// Pull every active req from your ATS.
const reqs = await fetch("https://your-ats.example.com/api/requisitions?active=true")
.then(r => r.json());
for (const r of reqs) {
const res = await fetch("https://www.astrishr.com/api/v1/jobs/sync", {
method: "POST",
headers: {
"Authorization": `Bearer ${KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
externalId: r.id, // your ATS's req id — used as upsert key
title: r.title,
location: r.location,
text: r.fullDescription,
}),
});
const data = await res.json();
console.log(`${r.id} → ${data.action} (${data.jobId})`);
}Run nightly via cron. The externalId upsert means re-runs are idempotent — closed reqs stay closed, edited reqs get updated.
POST /api/v1/jobs/bulk-sync
Same shape as /jobs/sync but accepts an array of up to 100 inputs. Processed sequentially to stay within Anthropic rate limits.
curl -X POST https://www.astrishr.com/api/v1/jobs/bulk-sync \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"jobs": [
{ "externalId": "ATS-1", "text": "Maintenance Tech…" },
{ "externalId": "ATS-2", "text": "Leasing Consultant…" }
]
}'{
"results": [
{ "jobId": "…", "slug": "…", "action": "created" },
{ "jobId": "…", "slug": "…", "action": "updated" }
],
"summary": { "total": 2, "created": 1, "updated": 1, "failed": 0 }
}GET /api/v1/jobs — list
List the most recent N jobs for the caller's employer. Use this to diff against your ATS state before deciding what to push.
curl https://www.astrishr.com/api/v1/jobs?limit=200 \
-H "Authorization: Bearer $KEY"{
"jobs": [
{
"id": "…",
"slug": "apartment-maintenance-tech-…",
"title": "Apartment Maintenance Tech",
"city": "Newark",
"state": "NJ",
"status": "open",
"postedAt": "2026-06-08T17:30:00Z",
"externalId": "ATS-12345"
}
]
}