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

Sessions come in three types:

Run Once (Job Array) — Apply to a specific list of job URLs immediately. Best for when users have already selected which jobs they want.

Autopilot Once — One-time automated job search with filters. The system finds matching jobs and applies automatically.

Autopilot Recurring — Scheduled automated applications that run on a configurable schedule (daily, weekly, or monthly).

Create Run Once Session

Apply to a specific list of jobs immediately. Pass the candidate profile ID and an array of up to 100 jobs. When testing with demo profiles, use overrideEmail to receive ATS confirmation emails at 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, "jobsQueued": 1 },
  "searchContext": { "titles": ["Senior Software Engineer"], "locations": [] },
  "createdAt": "2024-02-14T11:00:00Z"
}

Create Autopilot Recurring Session

Set up scheduled automated job search and applications. Configure a schedule pattern, search filters, and application limits.

POST/sessions/autopilot/recurring
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": "America/New_York" },
    "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",
          "schedule": {
            "pattern": "weekly",
            "daysOfWeek": ["monday", "wednesday"],
            "time": "09:00",
            "timezone": "America/New_York"
          },
          "filters": {
            "jobTitle": ["Software Engineer", "Backend Developer"],
            "location": ["San Francisco, CA"],
            "workType": ["Remote", "Hybrid"],
            "experience": ["Senior / Lead"]
          },
          "limits": { "maxJobsPerRun": 25 },
          "stats": { "totalRuns": 0, "totalApplications": 0, "successfulApplications": 0, "failedApplications": 0 },
          "createdAt": "2024-02-14T11:00:00Z"
        }

Get Session

Retrieve session details and statistics including total runs, application counts, next scheduled run time, and search context for autopilot sessions.

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, "jobsQueued": 25, "lastRunAt": "2024-02-14T09:00:00Z", "nextRunAt": "2024-02-16T09:00:00Z" },
  "searchContext": { "titles": ["Software Engineer"], "locations": ["San Francisco, CA"] },
  "createdAt": "2024-01-15T10:00:00Z"
}

List Sessions

Retrieve a paginated list of all sessions. Filter by status or type to find specific sessions.

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
              },
              "createdAt": "2024-01-15T10:00:00Z"
            }
          ],
          "pagination": { "page": 1, "limit": 20, "total": 8, "totalPages": 1 }
        }

Pause & Resume

Pause a recurring autopilot session to temporarily stop scheduled runs. Resume it later to continue from where it left off.

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_..."

Get Session Runs

Get execution history for a session. Each run includes stats on jobs found, applications attempted, and success/failure counts.

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 }
  }],
  "pagination": { "page": 1, "limit": 20, "total": 15, "totalPages": 1 }
}

Stop Session

Immediately stop a session. Cancels the session, marks any in-progress runs as cancelled, and prevents queued jobs from being processed. Jobs already being processed will finish naturally 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

Update the schedule, filters, or limits of an autopilot_recurring session. Only recurring sessions can be updated — other session types will return an error. If the session is active and the schedule is updated, 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": "America/New_York" },
    "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",
  "schedule": {
    "pattern": "daily",
    "time": "08:00",
    "timezone": "America/New_York"
  },
  "filters": {
    "jobTitle": ["Frontend Developer", "UI Engineer"],
    "location": ["Remote"],
    "workType": ["Remote"],
    "experience": ["Mid", "Senior / Lead"],
    "jobType": ["Full-time"]
  },
  "limits": { "maxJobsPerRun": 50 },
  "stats": { "totalRuns": 15, "totalApplications": 375, "successfulApplications": 320, "failedApplications": 55, "nextRunAt": "2024-02-15T13:00:00Z" },
  "createdAt": "2024-01-15T10:00:00Z"
}

Delete Session

Cancel and soft-delete a session. This sets the session status to cancelled and clears any scheduled next run. The session record is retained for historical reference 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)

Subscribe to real-time Server-Sent Events for a session. On connection, you immediately receive a session_sync event with the current session snapshot to catch up on any events already published. Then new events stream in real-time as applications are processed. The stream closes automatically when the session completes 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

Retrieve individual application results for a specific session. Use the sessionId query parameter on the Applications endpoint to get per-job details including status, error codes, and results.

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
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 }
}