> ## Documentation Index
> Fetch the complete documentation index at: https://docs.andteam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# New hires from an ATS

> POST /v1/hires creates a prefilled draft offer that HR completes.

An applicant tracking system hands a hire to andteam with `POST /v1/hires`. It creates a **prefilled
draft offer**, not a starter. In andteam a hire is final when the offer is signed. That is when
`employee.hired` is sent. Creating a starter directly would skip the hiring decision, the offer
approval and the letter, so the API does not.

HR opens the draft in the offer wizard with everything your ATS knew filled in, picks the contract
type and sends it. The approval chains run as they do for any offer. HR gets a task to complete the draft,
in the same list as offers started in andteam.

The call needs the **Hires** Write switch.

## The request

| Field | Meaning |
| - | - |
| `companyId` | The hiring company. |
| `candidate` | `firstName`, `lastName`, `preferredName`, `personalEmail`, `mobile`. |
| `startDate` | The planned first day. |
| `position` | An existing vacant `positionId`, or `new` with `jobTitle`, `orgUnitId`, `reportsToPositionId`, `locationId` and `employmentType`. |
| `hiringManagerId` | The hiring manager's employee id. |
| `pay` | Optional: `basis`, `currency` and `components[]`. |
| `externalRef` | Your ATS's `system` and `id` for the candidate. |

Never accepted: ID or passport numbers, race, disability or bank details. The candidate gives these in
onboarding, where they are gated.

```bash theme={null}
curl -X POST "https://api.v3.andteam.com/v1/hires" \
  -H "Authorization: Bearer atk_live_…" \
  -H "Idempotency-Key: 0b8e3f1a-7d1c-4e76-9a39-5f1c2b8d4e10" \
  -H "Content-Type: application/json" \
  -d '{
    "companyId": "cmp_…",
    "candidate": { "firstName": "Sipho", "lastName": "Dlamini", "personalEmail": "sipho@example.com" },
    "startDate": "2027-05-03",
    "position": { "positionId": "pos_…" },
    "hiringManagerId": "emp_3kTq…",
    "externalRef": { "system": "acme-ats", "id": "cand_4821" }
  }'
```

## The answer

201 with the hire's `id`, `status: "draft"` and `consoleUrl`, the offer wizard opened on the draft. Send
HR the link if your ATS shows one. Every POST needs an `Idempotency-Key`: see
[Retries and versions](https://docs.andteam.com/guides/idempotency.md).

## Statuses

A hire moves `draft`, `awaiting_approval`, `approved`, `sent`, `signed`. It can end as `withdrawn` or
`declined`. A hire is also `withdrawn` when the candidate's record is closed before the offer is signed. `GET /v1/hires/{id}` shows where it is, and reads back only hires the key filed.
`hire.status_changed` is sent on every move, with `data.hireId`, `data.status` and `data.externalRef`,
so your ATS can follow without polling. A webhook endpoint hears it with the Hires group.

## Duplicates

* The same `externalRef` again is 409 [`duplicate-hire`](https://docs.andteam.com/api/problems/duplicate-hire), with the
  existing hire's `existingId`. Read that hire instead of creating another.
* A candidate whose personal email matches a current employee is 409
  [`possible-rehire`](https://docs.andteam.com/api/problems/possible-rehire). Nothing is created. HR decides whether it is a
  rehire, and starts it in andteam.

## What andteam does not do

andteam is not an ATS. It has no requisitions or applications to read, and the API does not expose
recruitment. Candidates enter andteam through this call, and your ATS stays the record of who applied.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.