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

# Ingest

> Bulk-loading org structure: sources, record schemas, idempotency

`POST /developer/v1/ingest/{source_type}` accepts a batch of records from an
external system and queues it for asynchronous processing. Scope —
`ingest:write`; it is only available to keys created by super-administrators.

```bash theme={null}
curl -X POST -H "X-API-Key: ddp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sync-2026-02-10-001" \
  https://app.doodocs.kz/api/developer/v1/ingest/KEDO \
  -d '{
    "payload_type": "EMPLOYEES",
    "create_missing": true,
    "records": [ { "external_id": "emp-1001", "…": "…" } ]
  }'
```

<Warning>
  The `Idempotency-Key` header is **required**. Re-sending with the same key does
  not create a second load — you get an "ingest request already exists" error.
  If the batch content changes, change the key too.
</Warning>

## Sources and payload types

| `source_type` | `payload_type`   | What it loads                                   |
| ------------- | ---------------- | ----------------------------------------------- |
| `KEDO`        | `PERSONS`        | People (identity data)                          |
| `KEDO`        | `ORGANIZATIONS`  | Legal entities                                  |
| `KEDO`        | `DEPARTMENTS`    | Departments                                     |
| `KEDO`        | `EMPLOYEES`      | Employees                                       |
| `KEDO`        | `JOB_TITLES`     | Job titles                                      |
| `1C`          | `EMPLOYEES_FULL` | Employees together with persons (1C structures) |
| `1C`          | `DEPARTMENTS`    | Departments (1C structures)                     |

<Warning>
  An unknown source/payload pair is **not an error**: the request is accepted and
  the records are silently skipped (counted as "skipped" in the processing log).
  Double-check the spelling — a typo will not return a `400`.
</Warning>

## Matching by `external_id`

Every record carries an `external_id` — the object's identifier in your system.
The platform stores an `external_id → internal id` binding per `source_type`:

* a record with a known `external_id` **updates** the existing object;
* a record with a new `external_id` **creates** an object only when
  `create_missing: true`, otherwise it is skipped;
* references between records (`external_department_id`, `external_person_id`,
  etc.) also use external identifiers — the platform resolves them itself.

<Note>
  The `external_id` binding lives on the platform side and is **not returned** by
  `GET /employees`: the `Employee` object has no `external_id` field and no filter
  for it. To reconcile data after a load, keep the mapping on your side or rely on
  natural keys (the `employee_number`, the IIN).
</Note>

## Record schemas

Fields outside the schema are ignored. Dates are `YYYY-MM-DD` strings.

### KEDO · PERSONS

| Field                                                        | Description                                |
| ------------------------------------------------------------ | ------------------------------------------ |
| `external_id`                                                | Person identifier in the source (required) |
| `first_name`, `last_name`, `middle_name`                     | Full name                                  |
| `gender`                                                     | Gender                                     |
| `birth_date`, `birth_place`                                  | Date and place of birth                    |
| `iin`                                                        | IIN (national identification number)       |
| `number`, `serial_number`                                    | Identity document number and series        |
| `issued_date`, `issuing_authority`, `issuing_authority_code` | Document issuance                          |
| `registration_address`                                       | Registration address                       |
| `citizenship`                                                | Citizenship                                |
| `phone`, `email`                                             | Contacts                                   |

### KEDO · ORGANIZATIONS

| Field                                   | Description                           |
| --------------------------------------- | ------------------------------------- |
| `external_id`                           | Legal-entity identifier in the source |
| `title`                                 | Name                                  |
| `bin`                                   | BIN (business identification number)  |
| `legal_address`, `actual_address`       | Legal and actual addresses            |
| `bank_bik`, `bank_account`, `bank_name` | Bank details                          |

### KEDO · DEPARTMENTS

| Field                      | Description                                |
| -------------------------- | ------------------------------------------ |
| `external_id`              | Department identifier                      |
| `title`                    | Name                                       |
| `external_organization_id` | Legal-entity reference (its `external_id`) |
| `external_parent_id`       | Parent department (optional)               |

### KEDO · EMPLOYEES

| Field                          | Description                              |
| ------------------------------ | ---------------------------------------- |
| `external_id`                  | Employee identifier                      |
| `number`                       | Employee number                          |
| `admission_date`               | Hire date                                |
| `left_date`                    | Termination date (optional)              |
| `available_vacation_day_count` | Remaining vacation days (optional)       |
| `external_person_id`           | Person reference (`PERSONS.external_id`) |
| `external_organization_id`     | Legal-entity reference                   |
| `external_department_id`       | Department reference                     |
| `external_job_title_id`        | Job-title reference                      |

### KEDO · JOB\_TITLES

| Field         | Description          |
| ------------- | -------------------- |
| `external_id` | Job-title identifier |
| `title`       | Name                 |

### 1C · EMPLOYEES\_FULL

Records in the 1C export format — an employee together with the person, fields
in Russian: `ТабельныйНомер`, `ДатаПриема`, `Организация.Ссылка`,
`Подразделение.Ссылка`, `Должность.Ссылка`, and a nested `ФизЛицо` object
(`Имя`, `Фамилия`, `Отчество`, `ИИН`, `Телефон`, `ДатаРождения`).
`1C · DEPARTMENTS` — `Ссылка`, `Наименование`, `Родитель.Ссылка`.

## Response and tracking progress

```json theme={null}
{ "ingest_request_id": "8f4e…", "status": "ACCEPTED", "record_count": 120 }
```

Processing is asynchronous. **There is currently no status endpoint for an
`ingest_request_id`** — a preview limitation. Practical ways to confirm the
result:

1. Wait for processing (batches of hundreds of records take seconds).
2. Re-read the data: `GET /employees?updated_since=…` returns the created and
   updated employees.
3. Subscribe to the `employee.changed` webhook — every changed profile arrives
   as an event.

## Next steps

<Columns cols={2}>
  <Card title="Employee sync" icon="rotate" href="/en/guides/recipes/sync-employees">
    Full and incremental export back out.
  </Card>

  <Card title="Limits" icon="gauge" href="/en/api-reference/limits">
    Request rates and sizes.
  </Card>
</Columns>
