API Reference

Job Search

Search for jobs across supported ATS platforms by title, location, and filters. Every returned job can be applied to via the Sessions endpoint.

Overview

The Job Search endpoint lets you find open positions across all supported ATS platforms. Results are pre-filtered to only include jobs that can be submitted through the API — so every job you get back is ready to be passed directly to the Sessions apply endpoint.

This is useful for clients who don't have their own job feed and want to offer end-to-end search-and-apply functionality through a single API.

Search Jobs

Search for jobs by title, location, and optional filters. Returns a list of matching jobs with full details including company information, salary data, and direct application URLs.

POST/jobs/search
NameTypeRequiredDescription
titlesstring[]RequiredArray of job titles to search for (e.g. ["Software Engineer", "Frontend Developer"])
locationsstring[]OptionalArray of locations (e.g. ["Remote", "United States", "San Francisco, CA"])
postedAtMaxAgeDaysintegerOptionalMaximum age of job postings in days (default: 30)
resultsintegerOptionalTarget number of results to return (default: 50, max: 500)
excludeJobIdsstring[]OptionalArray of job IDs to exclude from results (e.g. previously applied jobs)
filtersobjectOptional
Optional filters to narrow results
FieldTypeRequiredDescription
workTypestringOptionalRemote, On-site, or Hybrid
jobTypestringOptionalfull-time, part-time, contract, or internship
experienceLevelstringOptionalintern, junior, mid, senior, lead, or executive
salaryMinintegerOptionalMinimum annual salary in USD (e.g. 100000)
companySizeMinintegerOptionalMinimum company employee count (e.g. 50)
curl -X POST https://apply-api.boringproject.ai/api/v1/jobs/search \
  -H "Authorization: Bearer bp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "titles": ["Software Engineer", "Full Stack Developer"],
    "locations": ["Remote", "San Francisco, CA"],
    "results": 25,
    "filters": {
      "workType": "Remote",
      "experienceLevel": "mid",
      "salaryMin": 100000
    }
  }'
Response200 OK
{
  "searchId": "srch_abc123",
  "query": "Software Engineer, Full Stack Developer",
  "resultsCount": 25,
  "jobs": [
    {
      "jobId": "48291",
      "title": "Senior Software Engineer",
      "companyName": "Acme Corp",
      "url": "https://boards.greenhouse.io/acme/jobs/48291",
      "jobBoard": "Greenhouse",
      "description": "We are looking for a Senior Software Engineer to join our platform team...",
      "datePosted": "2024-02-10",
      "location": "Remote, US",
      "salary": "$140,000 - $180,000",
      "salaryMin": 140000,
      "salaryMax": 180000,
      "salaryCurrency": "USD",
      "jobType": "full-time",
      "remote": true,
      "seniority": "senior",
      "companyDomain": "acmecorp.com",
      "logoUrl": "https://logo.clearbit.com/acmecorp.com",
      "companySize": 500,
      "companyIndustry": "Technology"
    },
    ...
  ]
}

Job Object Fields

Each job in the response array contains the following fields. Fields marked Always are guaranteed to be present. Fields marked Nullable may be null when data is not available.

NameTypePresenceDescription
jobIdstringAlwaysUnique job identifier
titlestringAlwaysJob title
companyNamestringAlwaysHiring company name
urlstringAlwaysDirect application URL — pass this as the link field in POST /sessions/apply
jobBoardstringAlwaysATS platform name (e.g. Greenhouse, Lever, Ashby)
descriptionstring | nullNullableFull job description text (may be null if source doesn't provide it)
datePostedstring | nullNullableDate the job was posted, YYYY-MM-DD (may be null)
locationstring | nullNullableJob location, e.g. "Remote, US" (may be null)
remotebooleanAlwaysWhether the job is remote
salarystring | nullNullableFormatted salary string (e.g. "$140,000 - $180,000")
salaryMinnumber | nullNullableMinimum annual salary in USD
salaryMaxnumber | nullNullableMaximum annual salary in USD
salaryCurrencystring | nullNullableSalary currency code
jobTypestringNullableEmployment type: full-time, part-time, contract, or internship
senioritystringNullableSeniority level of the role
companyDomainstringNullableCompany website domain
logoUrlstring | nullNullableCompany logo URL
companySizeinteger | nullNullableCompany employee count
companyIndustrystringNullableCompany industry

Search + Apply Flow

The typical workflow is to search for jobs, let the user select which ones to apply to, and then pass them to the Sessions apply endpoint. The job url field maps directly to the link field in the apply request.

Use the excludeJobIds parameter to pass previously applied job IDs and avoid duplicate applications.
# 1. Search for jobs
curl -X POST https://apply-api.boringproject.ai/api/v1/jobs/search \
  -H "Authorization: Bearer bp_live_..." \
  -H "Content-Type: application/json" \
  -d '{"titles": ["Software Engineer"], "locations": ["Remote"]}'

# 2. Apply to selected jobs (using job URLs from search results)
curl -X POST https://apply-api.boringproject.ai/api/v1/sessions/apply \
  -H "Authorization: Bearer bp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "candidateProfileId": "prof_xyz789",
    "jobs": [
      { "companyName": "Acme Corp", "title": "Senior Software Engineer", "jobId": "48291", "link": "https://boards.greenhouse.io/acme/jobs/48291" }
    ]
  }'

Automatic Deduplication

The API automatically excludes jobs that were returned in previous searches for your account within the last 24 hours. Each search only returns fresh, never-before-seen jobs — so you can call the search endpoint repeatedly without worrying about duplicates.

This works by tracking the job IDs returned in your recent search records (within a 24-hour rolling window). When a new search is performed, those job IDs are excluded server-side so results are always fresh.

For Autopilot Recurring sessions, deduplication is even more specific — it filters out jobs that the candidate has already applied to (regardless of success or failure), ensuring each recurring run only applies to genuinely new positions.

You don't need to manage excludeJobIds manually for deduplication — the API handles it automatically. The excludeJobIds parameter is still available for additional client-side exclusions if needed.

Filter Behavior

If fewer jobs match your filters than the requested results count, the API progressively relaxes filters to find more results. The relaxation order is: salary minimum and company size are dropped first, then experience level and job type, and finally work type and locations. This ensures you always get the most relevant results possible while still meeting your target count.

The titles parameter is never relaxed — results always match at least one of your specified job titles.

List Past Searches

Retrieve a paginated list of your previous job searches. Each record includes the search query, filters used, result count, and how many applications were submitted from that search.

GET/searches
NameTypeRequiredDescription
pageintegerOptionalPage number (default: 1)
limitintegerOptionalItems per page, max 100 (default: 20)
Response200 OK
{
  "data": [
    {
      "searchId": "srch_abc123",
      "query": "Software Engineer, Full Stack Developer",
      "titles": ["Software Engineer", "Full Stack Developer"],
      "locations": ["Remote", "San Francisco, CA"],
      "filters": { "workType": "Remote", "experienceLevel": "mid" },
      "resultsCount": 25,
      "totalAvailable": 2413,
      "totalCompanies": 1208,
      "appliedCount": 5,
      "createdAt": "2024-02-14T10:30:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 12, "totalPages": 1 }
}

Get Search Record

Retrieve a specific search record by ID, including the full jobs array. Use this to show the original search results or to let users select jobs to apply to from a previous search.

Pass the searchId when creating a run_once session to automatically populate the session's search context with the original search titles and locations.
GET/searches/:searchId
Response200 OK
{
  "searchId": "srch_abc123",
  "query": "Software Engineer",
  "titles": ["Software Engineer"],
  "locations": ["Remote"],
  "filters": {},
  "resultsCount": 25,
  "totalAvailable": 2413,
  "totalCompanies": 1208,
  "appliedCount": 5,
  "jobs": [
    {
      "jobId": "48291",
      "title": "Senior Software Engineer",
      "companyName": "Acme Corp",
      "url": "https://boards.greenhouse.io/acme/jobs/48291",
      "jobBoard": "Greenhouse",
      "location": "Remote, US",
      "salary": "$140,000 - $180,000",
      "remote": true
    }
  ],
  "createdAt": "2024-02-14T10:30:00Z"
}