Alfa API

Applicant intake

When candidates apply through your ATS, send each application to Alfa. Alfa screens the applicant like anyone who applied in Alfa and reports the result with the same webhooks.

Applicant intake needs a platform key with the applications:write scope, and an Alfa job linked to your ATS job.

Sending an applicant

Send an applicant
curl -X POST "https://api.welovealfa.com/v1/integration/applications" \
  -H "Authorization: Bearer $ALFA_API_KEY" \
  -H "Alfa-Company-Id: org_2abcDEF123" \
  -H "Content-Type: application/json" \
  -d '{"externalJobId":"job_8841","externalCandidateId":"cand_123","externalApplicationId":"appl_456","firstName":"Ada","lastName":"Lovelace","email":"ada@example.com","appliedAt":"2026-10-07T09:30:00Z","resume":{"fileName":"ada-lovelace.pdf","contentType":"application/pdf","contentBase64":"JVBERi0xLjcK…"}}'
FieldRequiredMeaning
externalJobIdRequiredYour ATS job, linked to an Alfa job.
externalCandidateIdRequiredYour id for the candidate.
externalApplicationIdRequiredYour id for this application. Alfa uses it to spot duplicates.
firstName, lastName, emailRequiredThe applicant.
phone, linkedinUrl, locationOptionalMore about the applicant.
appliedAtOptionalWhen they applied, as an ISO 8601 time.
screeningAnswersRequired when the job has mandatory questionsA list of { question, answer } for the screening questions the job lists in screeningQuestions. Quote each question exactly; an answer is true or false, a number or text.
resumeRequiredAn object with fileName, contentType and contentBase64 (the file, base64 encoded).

Resumes

The resume can be at most 4 MB once decoded (the whole request must stay under 6 MB), its content must match its contentType, and the type must be one of:

  • application/pdf
  • application/msword
  • application/vnd.openxmlformats-officedocument.wordprocessingml.document
  • text/plain

Responses and duplicates

  • 202 with { candidateId, jobId, status: "received" }: the applicant was added and will be screened.
  • 200 with status "existing": Alfa already has this externalApplicationId. Nothing new is created, and you get the same ids back.

An application counts as received only once its resume is attached and screening is queued. If a request fails before then, for example with invalid_resume, send it again with the same externalApplicationId and a corrected file: Alfa finishes the same application and answers 202.

Sending the same application twice is therefore safe. To retry a request whose response you did not get, you can also send an Idempotency-Key header.

What happens next

  • Alfa screens the applicant like any other applicant on the job.
  • Alfa sends the applicant no emails; your ATS stays in charge of contacting them.
  • The applicant counts toward the company's applicant limit.
  • candidate.screened and later candidate.status_changed webhooks carry your externalCandidateId and externalApplicationId, so you can match the result to the application.

Errors

StatusCodeWhen
422ats_job_not_linkedNo Alfa job is linked to the ATS job yet.
409job_not_accepting_applicationsThe linked Alfa job is not live, or is full.
409application_in_progressAnother request with the same externalApplicationId is still being processed. Retry it shortly.
409interview_only_jobThe linked Alfa job screens applicants through an AI interview, which applicant intake does not support.
422unsupported_resume_typeThe contentType is not one listed above.
422resume_too_largeThe decoded resume is larger than 4 MB.
422invalid_resumeThe resume is empty, is not valid base64, does not match its contentType, or cannot be read (for example a password-protected PDF).
422screening_questions_incompleteA mandatory screening question has no answer.
422unknown_screening_questionAn answer quotes a question the job does not have.
422validation_failedA field is missing or invalid.
403insufficient_scopeThe key does not have the applications:write scope.
429rate_limitedMore than 60 requests a minute for this key and company.

See the applicant intake reference, every error code and the changelog.