# Greenhouse 422 "email has already been taken" on candidate re-submit

## TL;DR
Greenhouse rejected the candidate create because that email already exists in the system; creates must be unique by email. Fix: catch the 422, look the candidate up by email, and add the new application to the existing candidate record instead of creating a duplicate. Search-then-attach beats blind create.

## Error
```text
422 Unprocessable Entity
"email has already been taken"
```

## Steps
1. On the 422, search for the existing candidate: call GET /v1/candidates with the email as the query parameter.
   Expected: 200 with the existing candidate record (or records).
2. If exactly one candidate matches, add the application under it: POST to /v1/candidates/[CANDIDATE_ID]/applications with the job ID and source.
   Expected: 201 Created for the new application.
3. If several candidates share the email, pick the right one by name and creation date, or merge per your team's dedupe policy before attaching.
   Expected: the application lands on the intended record, not a stale duplicate.
4. If no candidate matches (rare), the email may differ by casing or whitespace; normalize and search again before giving up.
   Expected: you rule out a false miss.
5. Make search-before-create the default path in the agent: always look up by email first, create only on no match.
   Expected: the 422 stops occurring.

## Use this when
- the agent submits candidates to the Greenhouse Harvest API
- re-submissions or re-engaged candidates 422
- the same person applies to a second job
- bulk imports hit existing emails

## Not for this skill when
- the error is 401 (that is the rotated-key problem)
- the 422 names a different field like first_name (that is the blank-first-name problem)
- you actually want a second record (Greenhouse dedupes by email, so reconsider)

## Variant phrasings
- "Greenhouse candidate already exists"
- "422 email taken Harvest API"
- "duplicate candidate email Greenhouse"
- "re-submit candidate application Greenhouse"

## Why it happens
Greenhouse treats candidate email as a unique identifier. The Harvest API create endpoint is not an upsert; submitting an existing email is a validation failure by design. Agents that create-then-handle-errors (or skip the lookup) hit this on every re-submission.

## Edge cases
- Candidates with multiple emails can legitimately create near-duplicates; dedupe on all known emails.
- The search endpoint paginates; check beyond the first page for common names.
- If your flow creates the candidate and the application in one call, split it: candidate upsert first, application second.
- Log the candidate ID you attached to, so later steps do not re-resolve differently.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_VHV40P9ZVURpXwCnzu2zvw
