API Reference

Sessions

Create and manage job application sessions — apply to specific jobs, run one-time searches, or set up recurring autopilot campaigns.

Session Types

The API supports the following session types:

**Run Once** — Submit applications to a specific list of job URLs immediately. Use this when your users have already selected the jobs they want to apply to.

**Autopilot Recurring** — Configure a schedule (daily, weekly, or monthly) and search filters. The system automatically finds new matching jobs and submits applications on each run.

Create Run Once Session

Creates a session that applies to a specific list of jobs immediately. Provide a candidate profile ID and an array of up to 100 jobs. When testing with demo profiles, use `overrideEmail` to route ATS confirmation emails to your own address.

POST/sessions/apply
NameTypeRequiredDescription
candidateProfileIdstringRequiredProfile to use for applications
searchIdstringOptionalSearch record ID from a previous POST /jobs/search response. When provided, the session's searchContext (titles and locations) is populated from that search record.
overrideEmailstringOptionalOverride the profile's email for this session. Useful with demo profiles so ATS confirmation emails go to your address.
jobsarrayRequired
List of jobs to apply to (max 100)
FieldTypeRequiredDescription
companyNamestringRequiredCompany name
titlestringRequiredJob title
jobIdstringRequiredYour job ID reference
linkstringRequiredJob application URL
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": "12345", "link": "https://boards.greenhouse.io/acme/jobs/12345"}
    ]
  }'
Response200 OK
{
  "sessionId": "sess_abc123",
  "type": "run_once",
  "userId": "usr_abc123",
  "candidateProfileId": "prof_xyz789",
  "status": "active",
  "stats": { "totalRuns": 1, "totalApplications": 0, "successfulApplications": 0, "failedApplications": 0, "applicationsSkipped": 0, "jobsQueued": 1 },
  "searchContext": { "titles": ["Senior Software Engineer"], "locations": [] },
  "createdAt": "2024-02-14T11:00:00Z"
}

Create Autopilot Recurring Session

Creates a recurring autopilot session that automatically searches for jobs and submits applications on a schedule. Configure the frequency, search filters, and a per-run application limit.

POST/sessions/autopilot/recurring
NameTypeRequiredDescription
candidateProfileIdstringRequiredProfile to use for applications.
scheduleobjectRequired
Schedule configuration for recurring runs.
FieldTypeRequiredDescription
patternstringRequiredSchedule pattern: daily, weekly, or monthly.
daysOfWeekstring[]OptionalDays to run (for weekly pattern). e.g. ["monday", "wednesday"].
timestringOptionalTime of day in HH:MM format. Defaults to 09:00.
timezonestringOptionalIANA timezone identifier. Defaults to UTC.
filtersobjectRequired
Job search filters applied on each run.
FieldTypeRequiredDescription
jobTitlestring | string[]OptionalJob title or list of titles to search for.
locationstring[]OptionalLocations to search in.
workTypestring[]OptionalWork types: Remote, On-site, Hybrid.
experiencestring[]OptionalExperience level filters.
jobTypestring[]OptionalJob type filters.
datePostedstringOptionalDate posted filter.
salaryRangestringOptionalSalary range filter.
companySizestringOptionalCompany size filter.
limitsobjectOptional
Application limits per run.
FieldTypeRequiredDescription
maxJobsPerRunintegerOptionalMaximum jobs to apply to per run. Defaults to 25.
curl -X POST https://apply-api.boringproject.ai/api/v1/sessions/autopilot/recurring \
  -H "Authorization: Bearer bp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "candidateProfileId": "prof_xyz789",
    "schedule": { "pattern": "weekly", "daysOfWeek": ["monday", "wednesday"], "time": "09:00", "timezone": "UTC" },
    "filters": { "jobTitle": ["Software Engineer", "Backend Developer"], "location": ["San Francisco, CA"], "workType": ["Remote", "Hybrid"], "experience": ["Senior / Lead"] },
    "limits": { "maxJobsPerRun": 25 }
  }'
Response200 OK
{
  "sessionId": "sess_abc123",
  "type": "autopilot_recurring",
  "userId": "usr_abc123",
  "candidateProfileId": "prof_xyz789",
  "status": "active",
  "stats": { "totalRuns": 0, "totalApplications": 0, "successfulApplications": 0, "failedApplications": 0, "applicationsSkipped": 0, "jobsQueued": 0, "lastRunAt": null, "nextRunAt": "2024-02-17T09:00:00Z" },
  "searchContext": { "titles": ["Software Engineer"], "locations": ["San Francisco, CA"] },
  "createdAt": "2024-02-14T11:00:00Z"
}

Get Session

Retrieves the full details of a session including its current status, cumulative statistics, schedule configuration, and search context.

GET/sessions/:sessionId
curl https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123 \
        -H "Authorization: Bearer bp_live_..."
Response200 OK
{
  "sessionId": "sess_abc123",
  "type": "autopilot_recurring",
  "userId": "usr_abc123",
  "candidateProfileId": "prof_xyz789",
  "status": "active",
  "stats": { "totalRuns": 15, "totalApplications": 375, "successfulApplications": 320, "failedApplications": 55, "applicationsSkipped": 0, "jobsQueued": 25, "lastRunAt": "2024-02-14T09:00:00Z", "nextRunAt": "2024-02-16T09:00:00Z" },
  "schedule": { "pattern": "weekly", "daysOfWeek": ["monday", "wednesday"], "time": "09:00", "timezone": "UTC" },
  "filters": { "jobTitle": "Software Engineer", "location": ["San Francisco, CA"], "workType": ["Remote"] },
  "limits": { "maxJobsPerRun": 25 },
  "searchContext": { "titles": ["Software Engineer"], "locations": ["San Francisco, CA"] },
  "createdAt": "2024-01-15T10:00:00Z"
}

List Sessions

Returns a paginated list of all sessions. Filter by status or session type to narrow results.

GET/sessions
NameTypeRequiredDescription
pageintegerOptionalPage number (default: 1)
limitintegerOptionalItems per page, max 100 (default: 20)
statusstringOptionalFilter: active, paused, completed, cancelled
typestringOptionalFilter: run_once, autopilot_recurring
curl "https://apply-api.boringproject.ai/api/v1/sessions?page=1&limit=20&status=active&type=autopilot_recurring" \
        -H "Authorization: Bearer bp_live_..."
Response200 OK
{
  "data": [
    {
      "sessionId": "sess_abc123",
      "type": "autopilot_recurring",
      "userId": "usr_abc123",
      "candidateProfileId": "prof_xyz789",
      "status": "active",
      "stats": { "totalRuns": 15, "totalApplications": 375, "successfulApplications": 320, "failedApplications": 55, "applicationsSkipped": 0, "jobsQueued": 25, "lastRunAt": "2024-02-14T09:00:00Z", "nextRunAt": "2024-02-16T09:00:00Z" },
      "schedule": { "pattern": "weekly", "daysOfWeek": ["monday", "wednesday"], "time": "09:00", "timezone": "UTC" },
      "filters": { "jobTitle": "Software Engineer", "location": ["San Francisco, CA"], "workType": ["Remote"] },
      "limits": { "maxJobsPerRun": 25 },
      "searchContext": { "titles": ["Software Engineer"], "locations": ["San Francisco, CA"] },
      "createdAt": "2024-01-15T10:00:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 8, "totalPages": 1 }
}

Pause & Resume

Pauses an active session to temporarily stop scheduled runs. Resuming restores the session to active status and recomputes the next run time for recurring sessions.

POST/sessions/:sessionId/pause
# Pause
curl -X POST https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123/pause \
  -H "Authorization: Bearer bp_live_..."

# Resume
curl -X POST https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123/resume \
  -H "Authorization: Bearer bp_live_..."
Response200 OK
// Pause response
{
  "sessionId": "sess_abc123",
  "type": "autopilot_recurring",
  "userId": "usr_abc123",
  "candidateProfileId": "prof_xyz789",
  "status": "paused",
  "stats": { "totalRuns": 15, "totalApplications": 375, "successfulApplications": 320, "failedApplications": 55, "applicationsSkipped": 0, "jobsQueued": 0, "lastRunAt": "2024-02-14T09:00:00Z", "nextRunAt": null },
  "schedule": { "pattern": "weekly", "daysOfWeek": ["monday", "wednesday"], "time": "09:00", "timezone": "UTC" },
  "filters": { "jobTitle": "Software Engineer", "location": ["San Francisco, CA"], "workType": ["Remote"] },
  "limits": { "maxJobsPerRun": 25 },
  "searchContext": { "titles": ["Software Engineer"], "locations": ["San Francisco, CA"] },
  "createdAt": "2024-01-15T10:00:00Z"
}

// Resume response
{
  "sessionId": "sess_abc123",
  "type": "autopilot_recurring",
  "userId": "usr_abc123",
  "candidateProfileId": "prof_xyz789",
  "status": "active",
  "stats": { "totalRuns": 15, "totalApplications": 375, "successfulApplications": 320, "failedApplications": 55, "applicationsSkipped": 0, "jobsQueued": 0, "lastRunAt": "2024-02-14T09:00:00Z", "nextRunAt": "2024-02-17T09:00:00Z" },
  "schedule": { "pattern": "weekly", "daysOfWeek": ["monday", "wednesday"], "time": "09:00", "timezone": "UTC" },
  "filters": { "jobTitle": "Software Engineer", "location": ["San Francisco, CA"], "workType": ["Remote"] },
  "limits": { "maxJobsPerRun": 25 },
  "searchContext": { "titles": ["Software Engineer"], "locations": ["San Francisco, CA"] },
  "createdAt": "2024-01-15T10:00:00Z"
}

Get Session Runs

Returns the execution history for a session. Each run includes timing information and statistics on jobs found, applications attempted, and their outcomes.

GET/sessions/:sessionId/runs
NameTypeRequiredDescription
pageintegerOptionalPage number (default: 1)
limitintegerOptionalItems per page, max 100 (default: 20)
statusstringOptionalFilter: in_progress, completed, failed, cancelled
curl "https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123/runs?page=1&limit=20&status=completed" \
        -H "Authorization: Bearer bp_live_..."
Response200 OK
{
  "data": [{
    "sessionRunId": "run_abc123",
    "sessionId": "sess_abc123",
    "startedAt": "2024-02-14T09:00:00Z",
    "completedAt": "2024-02-14T09:45:00Z",
    "status": "completed",
    "stats": { "jobsFound": 30, "applicationsAttempted": 25, "applicationsSuccessful": 22, "applicationsFailed": 3, "applicationsSkipped": 0 }
  }],
  "pagination": { "page": 1, "limit": 20, "total": 15, "totalPages": 1 }
}

Stop Session

Immediately and permanently stops a session. All in-progress runs are cancelled and queued jobs are prevented from processing. Jobs already being submitted to an ATS will complete, but no new jobs will be started.

Stopping a session is irreversible. The session status changes to cancelled and cannot be resumed. Use pause/resume for temporary interruptions.
POST/sessions/:sessionId/stop
curl -X POST https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123/stop \
  -H "Authorization: Bearer bp_live_..."

Update Recurring Session

Updates the schedule, search filters, or application limits of a recurring autopilot session. Only `autopilot_recurring` sessions can be updated. If the session is active and the schedule changes, the next run time is automatically recomputed.

Only autopilot_recurring sessions can be updated. Cancelled sessions cannot be modified. Other session types will return a 400 error.
PUT/sessions/:sessionId/recurring
scheduleobjectOptional
Updated schedule configuration
FieldTypeRequiredDescription
patternstringOptionalSchedule pattern: daily, weekly, or monthly
daysOfWeekstring[]OptionalDays to run (e.g. ["monday", "wednesday"]). Only used with weekly pattern.
timestringOptionalTime of day in HH:MM format (default: "09:00")
timezonestringOptionalIANA timezone (default: "UTC")
filtersobjectOptional
Updated search filters
FieldTypeRequiredDescription
jobTitlestring | string[]OptionalJob title(s) to search for. Accepts a single value or array.
locationstring[]OptionalLocations to search in
workTypestring[]OptionalWork types: "Remote", "On-site", or "Hybrid". Hybrid is treated as non-remote.
experiencestring[]OptionalExperience levels: "Junior", "Mid", "Senior / Lead", or "Executive"
jobTypestring[]OptionalEmployment types: "Full-time", "Part-time", "Contract", or "Internship"
datePostedstringOptionalRecency filter: "Past 24 hours", "Past week", or "Past month"
salaryRangestringOptionalMinimum salary filter (e.g. "$100k+", "$150k+")
companySizestringOptionalCompany size filter (e.g. "51-200", "201-1000", "5000+")
limitsobjectOptional
Updated application limits
FieldTypeRequiredDescription
maxJobsPerRunintegerOptionalMaximum jobs to apply to per run (default: 25)
curl -X PUT https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123/recurring \
  -H "Authorization: Bearer bp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": { "pattern": "daily", "time": "08:00", "timezone": "UTC" },
    "filters": { "jobTitle": ["Frontend Developer", "UI Engineer"], "location": ["Remote"], "workType": ["Remote"], "experience": ["Mid", "Senior / Lead"], "jobType": ["Full-time"] },
    "limits": { "maxJobsPerRun": 50 }
  }'
Response200 OK
{
  "sessionId": "sess_abc123",
  "type": "autopilot_recurring",
  "userId": "usr_abc123",
  "candidateProfileId": "prof_xyz789",
  "status": "active",
  "stats": { "totalRuns": 15, "totalApplications": 375, "successfulApplications": 320, "failedApplications": 55, "applicationsSkipped": 0, "jobsQueued": 0, "lastRunAt": "2024-02-14T09:00:00Z", "nextRunAt": "2024-02-15T08:00:00Z" },
  "schedule": { "pattern": "daily", "time": "08:00", "timezone": "UTC" },
  "filters": { "jobTitle": "Frontend Developer", "location": ["Remote"], "workType": ["Remote"] },
  "limits": { "maxJobsPerRun": 50 },
  "searchContext": { "titles": ["Frontend Developer"], "locations": ["Remote"] },
  "createdAt": "2024-01-15T10:00:00Z"
}

Delete Session

Cancels a session and clears any scheduled runs. The session record is retained for historical reference with a `cancelled` status but will no longer execute.

Returns 204 No Content with an empty body on success. The session is not hard-deleted — it remains queryable with status cancelled.
DELETE/sessions/:sessionId
curl -X DELETE https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123 \
  -H "Authorization: Bearer bp_live_..."

Session Events (SSE)

Opens a Server-Sent Events (SSE) stream for real-time session updates. On connection, you receive a `session_sync` event with the current session snapshot. Subsequent `application_update` events stream as each application is processed. The stream closes automatically when a `session_complete` event is emitted or when you disconnect.

This endpoint uses Server-Sent Events (SSE), not WebSockets. Use an SSE client library or the EventSource API in browsers. The stream uses Redis pub/sub internally so events are delivered in real-time.
GET/sessions/:sessionId/events
curl -N https://apply-api.boringproject.ai/api/v1/sessions/sess_abc123/events \
  -H "Authorization: Bearer bp_live_..." \
  -H "Accept: text/event-stream"
Response200 OK
event: session_sync
data: {"sessionId":"sess_abc123","stats":{"totalApplications":5,"successfulApplications":3,"failedApplications":1,"jobsQueued":1}}

event: application_update
data: {"application_id":"app_xyz789","job_url":"https://boards.greenhouse.io/acme/jobs/12345","status":"SUCCESS","timestamp":"2024-02-14T11:05:00Z"}

event: session_complete
data: {"sessionId":"sess_abc123","stats":{"totalApplications":5,"successfulApplications":4,"failedApplications":1,"jobsQueued":0}}

Get Applications by Session

Retrieves individual application results for a specific session. Use the `sessionId` query parameter on the Applications endpoint to get per-job details including status, errors, and outcomes.

Use this endpoint to show per-job breakdowns on session detail views — which jobs succeeded, which failed, and what errors occurred.
GET/applications?sessionId=sess_abc123
NameTypeRequiredDescription
sessionIdstringOptionalFilter applications by session ID
statusstringOptionalFilter by status: QUEUED, PROCESSING, SUCCESS, FAILED, CANCELLED, SKIPPED
pageintegerOptionalPage number (default: 1)
limitintegerOptionalItems per page, max 100 (default: 20)
curl "https://apply-api.boringproject.ai/api/v1/applications?sessionId=sess_abc123&status=SUCCESS&page=1&limit=20" \
        -H "Authorization: Bearer bp_live_..."
Response200 OK
{
  "data": [
    {
      "application_id": "app_abc123",
      "job_url": "https://boards.greenhouse.io/acme/jobs/12345",
      "job_title": "Senior Software Engineer",
      "company_name": "Acme Corp",
      "ats_type": "greenhouse",
      "status": "SUCCESS",
      "candidate_email": "john@example.com",
      "search_id": "srch_abc123",
      "result": { "confirmationUrl": "https://boards.greenhouse.io/acme/jobs/12345/confirmation" },
      "error": null,
      "created_at": "2024-02-14T11:00:00Z",
      "updated_at": "2024-02-14T11:05:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 5, "totalPages": 1 }
}