Первая подпись через API

Пять шагов: получить ключ, загрузить документ, создать сессию подписания, передать ссылку подписанту и получить результат. Все запросы — с ключом в заголовке Authorization.

  1. 1Получите ключ

    Зарегистрируйтесь и в кабинете, в разделе «Разработчикам», создайте ключ sandbox — сразу, без заявки. Ключ показывается один раз. Для подписей настоящими ключами ЭЦП (live) подайте заявку на боевой режим.

    Зарегистрироваться и получить ключ sandbox
    shell
    export ESIGN_KEY=sk_test_...   # ключ из кабинета → «Разработчикам»
  2. 2Загрузите документ

    Подойдут PDF, Word, Excel, изображения, TXT, CSV и XML до 20 МБ.

    POST /v1/documents
    curl https://e-sign.amir-amirov.kz/v1/documents \
      -H "Authorization: Bearer $ESIGN_KEY" \
      -F file=@contract.pdf
    
    # → { "id": "doc_01JBX4K9T6R2ZC8N5Q3W7Y1M0A", "status": "uploaded", ... }
  3. 3Создайте сессию подписания

    Укажите, чей ключ должен быть у каждого подписанта: ИИН, БИН и полномочия. Чужой ключ подпись не пройдёт.

    POST /v1/sign-sessions
    curl https://e-sign.amir-amirov.kz/v1/sign-sessions \
      -H "Authorization: Bearer $ESIGN_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: contract-114" \
      -d '{
        "document_id": "doc_01JBX4K9T6R2ZC8N5Q3W7Y1M0A",
        "signing_order": "sequential",
        "expires_in_hours": 72,
        "signers": [
          { "label": "Арендатор", "expected": { "iin": "900101300235" } },
          { "label": "Арендодатель",
            "expected": { "bin": "123456789013", "authority": "sign_right" } }
        ]
      }'

    В sandbox принимаются только тестовые ключи НУЦ, в live — только настоящие. Тестовые ключи можно скачать на pki.gov.kz.

  4. 4Передайте ссылку подписанту

    У каждого подписанта в ответе есть signing_url. Отправьте его любым способом: подписант откроет страницу e-sign и подпишет через NCALayer.

    201 Created
    {
      "id": "ses_01JBX5...",
      "status": "pending",
      "signers": [
        { "label": "Арендатор", "status": "pending",
          "signing_url": "https://e-sign.amir-amirov.kz/s/m0Z8oPpd..." },
        { "label": "Арендодатель", "status": "waiting", "signing_url": "..." }
      ]
    }

    Сейчас подписант подписывает на компьютере через NCALayer. Подписание с телефона через eGov Mobile временно недоступно: на телефоне страница подписания предложит открыть ссылку на компьютере.

  5. 5Получите результат

    Когда все подпишут, придёт webhook session.completed. Проверьте подпись запроса и скачайте пакет доказательств.

    webhook
    POST https://your-app.kz/webhooks/esign
    X-Signature: t=1761822145,v1=5f2c...
    
    { "id": "evt_01JBX6...", "type": "session.completed",
      "data": { "session": { "id": "ses_01JBX5...", "status": "completed",
                             "document_id": "doc_01JBX4K9T6R2ZC8N5Q3W7Y1M0A" } } }
    
    # пакет доказательств: документ, .cms, метки времени, OCSP, лист подписей
    curl -o evidence.zip https://e-sign.amir-amirov.kz/v1/documents/doc_01JBX4K9T6R2ZC8N5Q3W7Y1M0A/evidence \
      -H "Authorization: Bearer $ESIGN_KEY"

    Проверка подписи webhook

    Node.js
    import crypto from "node:crypto";
    
    // rawBody — тело запроса как строка, до JSON.parse
    export function verifyEsignWebhook(rawBody, header, secret) {
      const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
      if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // старше 5 минут
      const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
      return expected.length === v1.length &&
        crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
    }