Reqstaq API

The Reqstaq REST API lets you upload resumes for automatic parsing, organize the resulting candidate profiles into groups, and link them as applicants to your jobs. It powers our Zapier integration and is available to all Reqstaq accounts.

Base URL

https://reqstaq.com/api/v1

All endpoints accept and return JSON unless noted otherwise. All requests require HTTPS.

Authentication

Authenticate with a personal API token sent as a bearer token. Create one in Reqstaq under Settings → API Tokens (or from Settings → Integrations for Zapier). Tokens act as the user who created them and are scoped to the workspace that was active when the token was created.

curl https://reqstaq.com/api/v1/connection \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Requests without a valid, unexpired token receive 401 Unauthorized.

GET /connection

Verifies the token and identifies the authenticated user and workspace. Useful as a connection test.

{
  "user":    { "name": "Sarah McKinley", "email": "sarah@acme.com" },
  "account": { "id": 25, "name": "Acme Recruiting" }
}

GET /groups

Lists the workspace's manual groups visible to the authenticated user, ordered by name. Paginated with a 1-based page query parameter, 100 per page.

[
  { "id": 111, "name": "Active Pipeline" },
  { "id": 117, "name": "Enterprise Clients" }
]

GET /candidates

Lists the workspace's candidates, newest first. Paginated with a 1-based page query parameter, 100 per page.

[
  {
    "id": 1694,
    "name": "Likithesh Murali",
    "email": "likithesh@example.com",
    "created_at": "2026-06-10T21:14:02Z"
  }
]

POST /resume_intakes

Uploads one or more resumes for asynchronous parsing into candidate profiles. Send as multipart/form-data.

Parameters

Example

curl -X POST https://reqstaq.com/api/v1/resume_intakes \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "files[]=@resume.pdf" \
  -F "group_name=LinkedIn Inbound" \
  -F "job_posting_url=https://www.linkedin.com/jobs/view/4011223344/"

Response — 202 Accepted

Parsing happens in the background; poll the intake to track per-file progress.

{
  "id": 12,
  "status": "processing",
  "group": { "id": 3, "name": "LinkedIn Inbound" },
  "job":   { "id": 9, "title": "Staff Engineer", "matched": true },
  "items": [
    {
      "id": 1,
      "filename": "resume.pdf",
      "status": "pending",
      "candidate": null,
      "apply_status": null,
      "error": null
    }
  ]
}

GET /resume_intakes/:id

Returns the intake with per-file status. Intake status is processing, completed, or completed_with_errors. Item apply_status (when a job matched) is created, duplicate, unsupported_format, or missing_email.

{
  "id": 12,
  "status": "completed",
  "group": { "id": 3, "name": "LinkedIn Inbound" },
  "job":   { "id": 9, "title": "Staff Engineer", "matched": true },
  "items": [
    {
      "id": 1,
      "filename": "resume.pdf",
      "status": "completed",
      "candidate": { "id": 55, "name": "Jane Doe", "email": "jane@example.com" },
      "apply_status": "created",
      "error": null
    }
  ]
}

Errors

Failed requests return a consistent envelope:

{ "error": { "code": "group_not_found", "message": "Group not found" } }

Rate limits