Four ways onto the board
- Manually, with Add candidate on the pipeline board.
- Hosted careers page, at
/careers/your-address. Claim the address in Settings → Pipeline and the page is live at once, listing your open jobs with an apply form. - Your own career page, posting to the apply API. Cards created either way are chipped Applied via career page, because a candidate's own submission means something different from a recruiter adding them.
- CSV import, for applicants you already have in a spreadsheet. Chipped Imported from CSV.
The apply key
Open Pipeline and expand Bring in applicants (admins only). Generate the apply key there. It looks like iwk_… and is shown exactly once, at the moment it is issued.
- Rotate issues a new key and immediately stops the old one working.
- Revoke turns the apply API off for your company entirely.
Listing your open jobs
Your career page needs the job ids to submit against, so fetch them from your backend:
curl https://app.interviewwatch.com/api/careers/jobs \
-H "Authorization: Bearer iwk_YOUR_APPLY_KEY"
Each entry carries the job id, its name, its role, and a ready-made display string. Only open jobs are returned, so a closed job stops accepting applications on its own.
Posting an application
curl -X POST https://app.interviewwatch.com/api/careers/applications \
-H "Authorization: Bearer iwk_YOUR_APPLY_KEY" \
-H "Content-Type: application/json" \
-d '{"jobId":"<job id>","name":"Ada Lovelace","email":"[email protected]"}'
The key can also be sent as the X-InterviewWatch-Key header if that suits your stack better. The exact snippet for your account, with your key and a job id already filled in, is shown in the Bring in applicants panel.
Only jobId, name, and email are stored. Any other fields in the body are ignored, so you can post your whole form payload without stripping it first.
The response tells you what happened:
| Field | Meaning |
|---|---|
created | true for a new application (HTTP 201), false if this person already had a card on this job (HTTP 200). |
active | false means the existing card is already Hired or Rejected. It is left exactly as it was. |
stage, source | Where the card landed and how it got there. |
applicationId, candidateId | Ids you can store against your own record. |
Duplicates and returning applicants
Applications are idempotent per job and email. Someone who double-submits your form gets one card, not two, and your backend can answer "we already have you" instead of reporting a fresh application. The same person may apply to as many of your jobs as they like: one candidate identity, one card per job.
If a previous application ended in Hired or Rejected, a new submission does not resurrect it. Reopening a closed decision is a deliberate action a recruiter takes on the board.
CSV import
In the same panel, pick the job, choose the file, and click Import CSV.
- Header row with
nameandemailcolumns. - Add an optional
jobIdcolumn to spread one file across several jobs. Rows without it land on the job you picked.
name,email
Ada Lovelace,[email protected]
Grace Hopper,[email protected]
The import is per row and best effort: you get a count of added, already in the pipeline, and failed, with the failing line numbers named so you know which rows to fix. A bad job id fails that row, not the whole file.
Limits
| Limit | Value |
|---|---|
| CSV rows per import | 500 (split larger loads into several files) |
| CSV file size | 512 KB |
| Apply API | Rate limited per company and per source IP. A burst returns HTTP 429; retry after a short pause. |
Rate limits protect you from a bot spraying your board through your own career page. If a legitimate high-volume posting is hitting them, get in touch.