> ## 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.

# Подписание документа

> Сквозной путь: создать → маршрут → отправить → подписать → скачать

Здесь — полный путь от шаблона до подписанного PDF. Все шаги, кроме скачивания,
требуют области `documents:write`; скачивание — `documents:read`.

Один принцип важнее остальных: **подпись вы формируете сами**. Сервер никогда не
подписывает за вас — вы присылаете готовый base64-блок CMS/ЭЦП, созданный на стороне
клиента ключом владельца, а сервер его проверяет и записывает.

<Frame caption="Порядок вызовов: от создания до подписанного PDF">
  ```mermaid theme={null}
  %%{init: {'theme':'neutral'}}%%
  sequenceDiagram
      participant C as Ваш код
      participant K as NCALayer / eGov Mobile
      participant A as Doodocs People API
      C->>A: POST /documents (из шаблона)
      A-->>C: документ, status DRAFT
      C->>A: PUT /documents/{id}/route
      A-->>C: маршрут задан
      C->>A: POST /documents/{id}/_send
      A-->>C: status ON_APPROVAL / ON_SIGN
      C->>A: GET /documents/{id}
      A-->>C: route.steps[].participants[].id
      C->>K: подписать ключом владельца
      K-->>C: base64 CMS/ЭЦП
      C->>A: POST /documents/{id}/_sign (participant_id, signature)
      A-->>C: status COMPLETED
      C->>A: GET /documents/{id}/download?file_type=FILE_TYPE_PDF
      A-->>C: временная ссылка на PDF
  ```
</Frame>

<Steps>
  <Step title="Создать документ из шаблона">
    `POST /documents` создаёт черновик по шаблону. Инициатор проставляется сервером
    как сотрудник владельца ключа — подменить его нельзя.

    ```bash theme={null}
    curl -X POST -H "X-API-Key: ddp_ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
      https://app.doodocs.kz/api/developer/v1/documents \
      -d '{
        "title": "Приказ о приёме — Куляш Байсеитова",
        "type_id": "t1…",
        "template_id": "tpl_7c1a…",
        "template_version": 3,
        "template_values": {
          "employee_full_name": "Куляш Байсеитова",
          "position": "HR-менеджер",
          "start_date": "2026-02-10"
        },
        "subject_employee_ids": ["3f2a9c7e-…"]
      }'
    ```

    В ответе — созданный документ со статусом `DOCUMENT_STATUS_DRAFT`. Поля `number`,
    `date` и `organization_id` можно передать явно; иначе они проставляются по
    правилам тенанта.
  </Step>

  <Step title="Задать маршрут">
    `PUT /documents/{document_id}/route` задаёт шаги согласования и подписания.
    Каждый шаг — это `step_type`, `rule` и список `employee_ids`.

    ```bash theme={null}
    curl -X PUT -H "X-API-Key: ddp_ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
      https://app.doodocs.kz/api/developer/v1/documents/8c2d…/route \
      -d '{
        "steps": [
          { "step_type": "STEP_TYPE_APPROVAL", "rule": "STEP_RULE_ANY_ONE", "employee_ids": ["mgr_ax…"] },
          { "step_type": "STEP_TYPE_SIGNING",  "rule": "STEP_RULE_ALL",     "employee_ids": ["9b7f…"] }
        ]
      }'
    ```

    `step_type` — `STEP_TYPE_APPROVAL` (согласование) или `STEP_TYPE_SIGNING`
    (подписание). `rule` — `STEP_RULE_ALL` (нужны все участники) или
    `STEP_RULE_ANY_ONE` (достаточно одного). Документ остаётся в `DRAFT` — маршрут
    ещё не запущен. У уже запущенного документа непройденные шаги правит
    `POST /documents/{document_id}/route/_modify`.
  </Step>

  <Step title="Отправить по маршруту">
    `POST /documents/{document_id}/_send` запускает маршрут: `DRAFT` переходит в
    `ON_APPROVAL` или `ON_SIGN`.

    ```bash theme={null}
    curl -X POST -H "X-API-Key: ddp_ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
      https://app.doodocs.kz/api/developer/v1/documents/8c2d…/_send \
      -d '{ "initial_action": "SEND_INITIAL_ACTION_SEND_ONLY" }'
    ```

    `initial_action` по умолчанию `SEND_INITIAL_ACTION_SEND_ONLY` — просто отправить.
    Значения `…_APPROVE_FIRST_STEP` и `…_SIGN_FIRST_STEP` сразу закрывают первый шаг
    от имени инициатора (тогда вместе с ними передаются `signature` и `sign_method`)
    и доступны только инициатору.
  </Step>

  <Step title="Найти свой participant_id">
    Прочитайте документ и возьмите `id` своего активного участника из
    `route.steps[].participants[]` — именно он передаётся в подписание и согласование.

    ```bash theme={null}
    curl -H "X-API-Key: ddp_ВАШ_КЛЮЧ" \
      https://app.doodocs.kz/api/developer/v1/documents/8c2d…
    ```

    ```json theme={null}
    {
      "route": {
        "steps": [
          {
            "step_type": "STEP_TYPE_SIGNING",
            "participants": [
              { "id": "p1…", "employee_id": "9b7f…", "status": "PARTICIPANT_STATUS_PENDING" }
            ]
          }
        ]
      }
    }
    ```
  </Step>

  <Step title="Подписать">
    `POST /documents/{document_id}/_sign` записывает подпись. `signature` — это
    готовый base64-блок CMS/ЭЦП, созданный на стороне клиента (десктопный NCALayer
    или eGov Mobile). Сервер его проверяет и фиксирует.

    **Что именно подписывать.** CMS формируется над содержимым PDF-файла
    документа — того, который закреплён за маршрутом при отправке. Скачайте его
    через `GET /documents/{document_id}/download` (`file_type=FILE_TYPE_PDF`) и
    подписывайте именно эти байты. В NCALayer это метод
    `createCMSSignatureFromBase64` с base64-содержимым PDF. Сервер сверяет
    подпись с дайджестами этого файла — CMS над другим содержимым будет
    отклонён.

    ```bash theme={null}
    curl -X POST -H "X-API-Key: ddp_ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
      https://app.doodocs.kz/api/developer/v1/documents/8c2d…/_sign \
      -d '{
        "participant_id": "p1…",
        "signature": "MIIFx…base64_CMS…",
        "sign_method": "SIGN_METHOD_NCALAYER"
      }'
    ```

    `sign_method` — `SIGN_METHOD_NCALAYER` или `SIGN_METHOD_EGOV_MOBILE`. Когда
    подписан последний обязательный шаг, документ переходит в
    `DOCUMENT_STATUS_COMPLETED`.

    <Warning>
      Подпись формируется на стороне клиента ключом владельца — сервер её не создаёт.
      Приватный ключ и генерация CMS/ЭЦП остаются у вас; в API уезжает только готовый
      base64-блок. Не отправляйте приватный ключ на сервер.
    </Warning>
  </Step>

  <Step title="Скачать подписанный PDF">
    `GET /documents/{document_id}/download` возвращает временную ссылку на файл.
    `file_type` по умолчанию `FILE_TYPE_PDF` — подписанный PDF.

    ```bash theme={null}
    curl -H "X-API-Key: ddp_ВАШ_КЛЮЧ" \
      "https://app.doodocs.kz/api/developer/v1/documents/8c2d…/download?file_type=FILE_TYPE_PDF"
    ```

    ```json theme={null}
    { "url": "https://storage.doodocs.kz/…/signed.pdf?X-Amz-Signature=…" }
    ```

    Другие типы файлов — `FILE_TYPE_PREVIEW` (печатная форма), `FILE_TYPE_DDCARD`
    (карточка КЭД), `FILE_TYPE_DOCX`, `FILE_TYPE_JSON`.
  </Step>
</Steps>

## Согласование, отклонение, доработка, отзыв

Кроме подписания, участник действует на **своём** активном слоте — `participant_id`
берётся из того же `route.steps[].participants[].id`.

| Ручка                                   | Действие                                                                                 |
| --------------------------------------- | ---------------------------------------------------------------------------------------- |
| `POST /documents/{id}/_approve`         | Согласовать шаг. Тело: `participant_id`, `comment`? (не обязателен)                      |
| `POST /documents/{id}/_reject`          | Отклонить → `REJECTED`. Тело: `participant_id`, `comment` (обязателен)                   |
| `POST /documents/{id}/_request_changes` | Запросить изменения → `CHANGE_REQUESTED`. Тело: `participant_id`, `comment` (обязателен) |
| `POST /documents/{id}/_revoke`          | Отозвать документ в работе → `REVOKED`. Доступно инициатору или руководителю             |

```bash theme={null}
curl -X POST -H "X-API-Key: ddp_ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
  https://app.doodocs.kz/api/developer/v1/documents/8c2d…/_approve \
  -d '{ "participant_id": "p1…", "comment": "Согласовано" }'
```

<Note>
  `_approve`, `_reject` и `_request_changes` действуют на активный слот вызывающего.
  Чтобы узнать, какой шаг сейчас активен и какой у вас `participant_id`, перечитайте
  документ через `GET /documents/{document_id}`.
</Note>

## Дальше

<Columns cols={2}>
  <Card title="Шаблоны" icon="file-lines" href="/ru/guides/documents/templates">
    Как прочитать `variable_schema` перед созданием.
  </Card>

  <Card title="События" icon="bell" href="/ru/guides/documents/events">
    Ловите `document.completed` вместо опроса статуса.
  </Card>
</Columns>
