Перейти до основного вмісту
Certyneo
Публічний API v1

Інтегруйте електронний підпис у ваш стек

Надсилайте конверти, відстежуйте підписи, отримуйте вебхуки. Простий REST API, OpenAPI 3.0, приклади curl/Node/Python — усе для підключення Certyneo до вашого HRIS, CRM або бізнес-програми за кілька годин.

Швидкий старт

Три кроки: створіть API ключ з параметрів, закодуйте ваш PDF в base64, надішліть. Відповідь містить `signUrl`, який ви можете поділитися безпосередньо з одержувачем.

cURLbash
# 1. Upload the PDF (multipart) and capture the returned document id.
DOC_ID=$(curl -s -X POST https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@contrat.pdf" | jq -r .id)

# 2. Create a DRAFT envelope referencing the uploaded document.
ENV_ID=$(curl -s -X POST https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d "{
    \"subject\": \"Contrat de prestation\",
    \"documentIds\": [\"$DOC_ID\"],
    \"recipients\": [
      { \"email\": \"client@example.com\", \"name\": \"Marie Dubois\", \"role\": \"SIGNER\" }
    ]
  }" | jq -r .id)

# 3. Dispatch the envelope — this sends the invitation email/SMS.
curl -X POST https://certyneo.com/api/v1/envelopes/$ENV_ID/send \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
JavaScript / Nodets
// Plain fetch, no SDK to install.
const auth = { Authorization: `Bearer ${process.env.CERTYNEO_API_KEY}` };

// 1. Upload the PDF (multipart).
const fd = new FormData();
fd.append("file", new Blob([pdfBuffer], { type: "application/pdf" }), "contrat.pdf");
const doc = await fetch("https://certyneo.com/api/v1/documents", {
  method: "POST", headers: auth, body: fd,
}).then((r) => r.json());

// 2. Create the DRAFT envelope.
const envelope = await fetch("https://certyneo.com/api/v1/envelopes", {
  method: "POST",
  headers: { ...auth, "Content-Type": "application/json" },
  body: JSON.stringify({
    subject: "Contrat de prestation",
    documentIds: [doc.id],
    recipients: [
      { email: "client@example.com", name: "Marie Dubois", role: "SIGNER" },
    ],
  }),
}).then((r) => r.json());

// 3. Dispatch — this triggers the invitation channel for every recipient.
await fetch(`https://certyneo.com/api/v1/envelopes/${envelope.id}/send`, {
  method: "POST", headers: auth,
});
console.log(envelope.id);
Pythonpython
import os, requests

auth = {"Authorization": f"Bearer {os.environ['CERTYNEO_API_KEY']}"}

# 1. Upload the PDF (multipart).
with open("contrat.pdf", "rb") as f:
    doc = requests.post(
        "https://certyneo.com/api/v1/documents",
        headers=auth,
        files={"file": ("contrat.pdf", f, "application/pdf")},
    ).json()

# 2. Create the DRAFT envelope.
envelope = requests.post(
    "https://certyneo.com/api/v1/envelopes",
    headers={**auth, "Content-Type": "application/json"},
    json={
        "subject": "Contrat de prestation",
        "documentIds": [doc["id"]],
        "recipients": [
            {"email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER"},
        ],
    },
).json()

# 3. Dispatch — this triggers the invitation channel for every recipient.
requests.post(
    f"https://certyneo.com/api/v1/envelopes/{envelope['id']}/send",
    headers=auth,
)
print(envelope["id"])

Спробуйте API за допомогою своїх інструментів

Колекція Postman і картка RapidAPI створюються зі специфікації OpenAPI, яка також документує цю сторінку. Усі три залишаються узгодженими з реальним API, endpoint за endpoint, замість того щоб розходитися при першому додаванні.

Колекція Postman

25 запити організовані за доменами — конверти, документи, шаблони, печатки, вебгаки — з прикладом тіла та відповіді для кожного. Вставте свій ключ у змінну apiKey колекції, потім запустіть GET /health: вона не вимагає жодної автентифікації та підтверджує, що ваша конфігурація правильна перед першим автентифікованим викликом.

Картка RapidAPI

Той же каталог endpoints, який можна протестувати прямо з браузера. Тестовий стенд очікує два окремі заголовки: ключ RapidAPI, який вам надає платформа, та ваш ключ Certyneo в Authorization — другий дійсно авторизує виклик.

Конверти

Створення, відправка, відстеження статусу, скасування. Конверт може містити кілька документів і кількох підписувачів (паралельно або послідовно).

Вебхуки

Усі події конверта та одержувача (`envelope.sent`, `recipient.signed`, `envelope.completed`…) доставляються на URL на вашу вибір — повний список на /developers/webhooks. HMAC SHA-256 для кожного пакету для перевірки походження.

Просте аутентифікування

Bearer token. Один ключ для кожного середовища (тест / прод). Можна миттєво відкликати. Ліміт 100 запитів/хв/ключ, виділення до 200, чистий 429 з заголовком Retry-After.

Доступні endpoint'и

53 публічних маршрутів: обліковий запис, документи, конверти, шаблони, вебхуки, електронні печатки, ключі API та виставлення рахунків. Усі приймають токен Bearer і повертають JSON.

МетодШляхОпис
GET/api/v1/account/meІдентичність аутентифікованого абонента (id, електронна пошта, план) : тест ідентифікаторів без необхідної области
GET/api/v1/sandboxПідрахувати дані, створені тестовими ключами (автоматично видаляються через 30 днів)
DELETE/api/v1/sandboxВидалити всі дані, створені тестовими ключами, не зачіпаючи реальних даних
POST/api/v1/documentsЗавантажити PDF (multipart) : повертає id документа
GET/api/v1/documentsПерелічити документи
GET/api/v1/documents/{id}Прочитати метаданні документа
DELETE/api/v1/documents/{id}Видалити документ
GET/api/v1/envelopesПерелічити конверти (фільтрувати за допомогою ?status= та ?limit=)
POST/api/v1/envelopesСтворити конверт (статус DRAFT) : із templateId або з documentIds із необов'язковим масивом полів
GET/api/v1/envelopes/{id}Прочитати стан конверта
PATCH/api/v1/envelopes/{id}Змінити конверт DRAFT
DELETE/api/v1/envelopes/{id}Видалити конверт DRAFT (409 після відправлення : скасуйте замість цього)
POST/api/v1/envelopes/{id}/sendВідправити конверт DRAFT : надіслати запрошення
POST/api/v1/envelopes/{id}/voidСкасувати відправлений конверт, який ще не повністю підписаний : очікуючих підписантів повідомляють
POST/api/v1/envelopes/{id}/remindПовторно надіслати за запитом підписантів, які очікують на відправлену конверту (конкретний одержувач необов'язково)
GET/api/v1/envelopes/{id}/audit-trailЗавантажити PDF журналу доказів eIDAS
POST/api/v1/envelopes/{id}/embed-urlПовертає URL підпису одержувача з дозволом обрамлення для запитаного походження. Викликайте під час натиснення: дозвіл діє дві години.
GET/api/v1/audit-anchors/{root}Публічні : метаданні закріпленої партії аудиту або файл доказів .ots із ?format=ots (без аутентифікації)
POST/api/v1/audit-anchors/verifyПублічні : перевірити запис аудиту та його доказ проти закріпленого кореня Меркла (без аутентифікації, нічого не розкриває)
GET/api/v1/envelopes/{id}/signed-documentЗавантажити підписаний PDF (після COMPLETED)
GET/api/v1/envelopes/bulkСписок ваших масових розсилок
POST/api/v1/envelopes/bulkМасова розсилка : створити N конвертів на основі шаблону та CSV (тільки Standard/Business)
GET/api/v1/envelopes/bulk/{id}Прогрес масової розсилки : лічильники, помилки за рядком, створені конверти
GET/api/v1/templatesСписок шаблонів конвертів, які можна використовувати повторно
POST/api/v1/templatesСтворити шаблон (документи, ролі, розташовані поля)
GET/api/v1/workspacesПерелічити робочі простори, у яких ви можете створити конверт
POST/api/v1/sepa-mandatesГенерувати PDF мандату SEPA та його конверт DRAFT, поля вже розташовані
POST/api/v1/payroll-adapters/normalizeНормалізувати CSV платіжної відомості (Silae, Sage Paie, PayFit, Lucca) у форматі масової розсилки
POST/api/v1/ag-coproprieteСтворити конверт загального зібрання власників нерухомості (резолюції та частки)
POST/api/v1/ag-copropriete/{envelopeId}/votesЗаписати голоси власника нерухомості щодо резолюцій зібрання
POST/api/v1/ag-copropriete/{envelopeId}/tallyПідрахувати зібрання : результат за резолюцією, зважений на частки
GET/api/v1/videos/{videoId}Завантажити відео ідентифікації : право доступу RGPD (ст. 15)
GET/api/v1/webhooksСписок webhook'ів
POST/api/v1/webhooksЗареєструвати webhook : повертає секрет підпису один раз
GET/api/v1/webhooks/{id}Прочитати підписку webhook
PATCH/api/v1/webhooks/{id}Змінити URL, події або активний стан
DELETE/api/v1/webhooks/{id}Відписати webhook
POST/api/v1/sealsНакласти кваліфіковану електронну печатку на документ
GET/api/v1/seals/{id}Прочитати статус печатки
GET/api/v1/seals/{id}/certificateЗавантажити сертифікат печатки
GET/api/v1/payslips/workspacesПлатіжні відомості : простори, для яких цей ключ розповсюджує, утримує або делегує клієнт (облікові фірми, менеджери платіжних відомостей)
GET/api/v1/payslips/employeesРозрахункові листки: реєстр працівників, включаючи тих, хто відмовився від електронної доставки (необхідна паперова версія)
PUT/api/v1/payslips/employeesРозрахункові листки: додавання або оновлення працівників у реєстрі (ніколи не видаляються)
POST/api/v1/payslipsНадіслати розрахунковий листок (PDF) у сейф працівника: запечатаний, зберігається 50 років, повторне надіслання без дублювання
GET/api/v1/payslipsСписок виданих розрахункових листків з доказом їх перегляду
GET/api/v1/keysСписок ключів API
POST/api/v1/keysСтворити ключ API: секрет відображається тільки один раз
PATCH/api/v1/keys/{id}Перейменувати або відкликати ключ
DELETE/api/v1/keys/{id}Видалити ключ
GET/api/v1/billing/usageСпоживання поточного періоду та прогнозована вартість
GET/api/v1/statusСтан сервісу
GET/api/v1/healthПеревірка здоров'я: база даних, черга та об'єктовий склад
GET/api/v1/openapiСпецифікація OpenAPI, придатна для читання машиною

Моделі обвертки

Шаблон записує один раз назавжди PDF, ролі та розташування полів підпису, потім повторно використовується при кожному відправленні: передайте його ідентифікатор у templateId замість documentIds, і позиціоновані поля копіюються на створений конверт.

  • • Шаблони створюються на панелі приладів (Шаблони → Новий шаблон), де ви завантажуєте документ і позиціонуєте поля мишею — це найпростіший шлях. API також дозволяє створювати їх через POST /api/v1/templates, надаючи документи, ролі та поля; будьте обережні, поля там позиціонуються в абсолютних координатах (сторінка, x, y, ширина, висота), тому ви повинні знати макет PDF.
  • • На обліковому записі, який ще не записав жодного шаблону, GET /api/v1/templates повертає порожній список. Це нормальна поведінка, а не дефект автентифікації.
  • • Список містить тільки шаблони, які належать користувачу-власнику ключа API. Шаблон, створений колегою, там не відображається, навіть у межах спільного робочого простору: створіть ключ з облікового запису, який володіє шаблоном.
  • • templateId та documentIds взаємно виключають один одного: надішліть один або інший, але ніколи обидва й ніколи жоден.
  • • Надайте щонайменше стільки отримувачів SIGNER, скільки ролей підписувачів має шаблон, інакше створення відхиляється з кодом 400. Поле signerCount, повернене списком, вказує очікуване число.
  • • Рівень підпису шаблону успадковується конвертом, якщо запит не передає явно signatureLevel.
cURLbash
# 1. Discover the templates saved on this account.
curl -s https://certyneo.com/api/v1/templates \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

# {
#   "data": [
#     { "id": "cmdq7f4k80001s6y2h1xa9pl3", "name": "Contrat de prestation",
#       "signerCount": 2, "documentCount": 1, "signatureLevel": "SIMPLE" }
#   ],
#   "pagination": { "page": 1, "pageSize": 20, "total": 1, "pages": 1 }
# }
#
# An empty "data" array means no template exists on this account yet —
# create one from the dashboard, it is not an authentication problem.

# 2. Create the envelope FROM the template: no documentIds and no field
#    coordinates, both are carried by the template. Pass one SIGNER
#    recipient per signer role, in the template's role order.
curl -X POST https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Contrat de prestation",
    "templateId": "cmdq7f4k80001s6y2h1xa9pl3",
    "recipients": [
      { "email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER" },
      { "email": "legal@example.com", "name": "Paul Martin", "role": "SIGNER" }
    ]
  }'

# 3. The envelope is DRAFT at this point — POST /envelopes/{id}/send
#    dispatches it, exactly as in the quick-start above.

З Power Automate або Zapier

Дія «Створити конверт» у наших no-code-розширеннях охоплює лише шлях за шаблоном: поле Шаблон там є обов'язковим. Для спеціального документа, який змінюється при кожному виконанні, використовуйте дію «Завантажити документ», а потім сиру дію HTTP до POST /api/v1/envelopes, передавши повернений documentIds.

Надсилання документа: два прийняті формати

POST /api/v1/documents приймає файл двома способами на вибір. Однакові перевірки застосовуються в обох випадках: дозволені типи, ліміт 50 МБ, перевірка бінарного підпису та антивірусний аналіз.

  • • У форматі multipart/form-data з частиною з назвою file. Це класичний формат, який використовують curl -F та більшість бібліотек.
  • • У вигляді сирого тіла: байти файлу утворюють тіло запиту, а заголовок Content-Type вказує його тип (наприклад, application/pdf). Корисно для інструментів, які передають вміст як є, без обгортання запиту — саме це робить сполучник Power Automate.
  • • У сирому тілі назва файлу не має місця в тілі: вкажіть її через заголовок X-File-Name або параметр ?fileName=. Без неї документ названий за його типом.
  • • Непідтримуваний тип відповідає 415, назвавши обидва прийняті формати, а тіло, оголошене як multipart, але нечитабельне, відповідає 400. Ні те, ні інше не є помилкою сервера.
cURLbash
# a. multipart/form-data — the classic shape.
curl -X POST https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@contrat.pdf;type=application/pdf"

# b. raw body — the file bytes ARE the body, typed by Content-Type.
#    The filename has nowhere to live in the body, so pass it as a header
#    (or ?fileName=). Without it the document is named after its type.
curl -X POST https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/pdf" \
  -H "X-File-Name: contrat.pdf" \
  --data-binary "@contrat.pdf"

# Both return the same 201 with the document id to pass as documentIds.

Розташування полів підпису

Без шаблону конверт, створений на основі documentIds, не має жодного попередньо розташованого поля: підписувач отримує документ без місця для підпису. Масив fields, переданий у тому ж виклику створення, розташовує кожне поле з точністю до пункту — це еквівалент на стороні API того, що шаблон записує раз і назавжди.

  • • Координати в пунктах PDF, початок координат у верхньому лівому кутку сторінки й вісь Y спрямована вниз (сторінка A4 вимірює 595 × 842 пункти). x та y позначають верхній лівий кут поля, width та height — його розмір.
  • • pageNumber починається з 1, documentIndex починається з 0. Номер сторінки, що виходить за межи документа, не відхиляється при створенні: поле ігнорується під час підпису й ніде не з'являється — це перша річ, яку варто перевірити, коли поле відсутнє у виклику.
  • • recipientEmail має відповідати одному з отримувачів того ж виклику, незалежно від регістру. Інакше створення не вдається й виводить список усіх помилкових рядків, що уникає потреби виправляти їх по одному.
  • • fields та templateId взаємно виключають один одного: шаблон уже несе власне розташування. Масив fields тому використовується лише з documentIds.
  • • Прийняті типи: SIGNATURE, INITIALS, DATE_SIGNED, TEXT, CHECKBOX та RADIO_GROUP. required за замовчуванням true; placeholder та dateFormat факультативні, а options враховується лише для RADIO_GROUP.
  • • Конверт приймає максимум 100 полів, 20 документів та 50 отримувачів — межі вашого плану можуть бути нижчими.
cURLbash
# Ad-hoc envelope WITH pre-placed fields — no template involved.
# Coordinates are PDF points, origin TOP-LEFT of the page, +Y downwards
# (A4 = 595 x 842 pt). x / y are the field box's top-left corner.
#
# The last field is positioned by ANCHOR instead of by eye: the server
# locates "Signature du client" in the PDF and computes the spot. x / y
# stay required there — they are the fallback if the text is not found.
curl -X POST https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Contrat de prestation",
    "documentIds": ["cmdq7f4k80001s6y2h1xa9pl3"],
    "recipients": [
      { "email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER" }
    ],
    "fields": [
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "SIGNATURE",
        "x": 90, "y": 640, "width": 180, "height": 44 },
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "DATE_SIGNED",
        "x": 320, "y": 640, "width": 140, "height": 30,
        "dateFormat": "DD/MM/YYYY" },
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "TEXT",
        "x": 90, "y": 700, "width": 200, "height": 30,
        "placeholder": "Fonction", "required": false },
      { "recipientEmail": "client@example.com", "documentIndex": 0,
        "pageNumber": 2, "fieldType": "SIGNATURE",
        "anchorText": "Signature du client", "anchorPlacement": "below",
        "anchorIndex": 0,
        "x": 90, "y": 640, "width": 180, "height": 44 }
    ]
  }'

# The envelope is DRAFT at this point — POST /envelopes/{id}/send
# dispatches it, exactly as in the quick-start above.

Текстові якорі: розташування поля без знання координат

Замість координат поле може посилатися на текст, надрукований у документі: anchorText знаходить його в PDF, і сервер обчислює позицію при створенні. Це режим, який варто пріоритизувати, коли документ регенерується при кожному відправленні — масова розсилка, генератор контрактів — оскільки розташування змінюється, а напис «Підпис клієнта» залишається. anchorPlacement вказує, з якого боку тексту розташовується поле (за замовчуванням right, інакше below, above або left), а anchorIndex вибирає входження, коли текст з'являється кілька разів.

x та y залишаються обов'язковими навіть з якорем: вони служать резервним варіантом. Невідшукуваний якір не робить створення невдалим — поле зберігає буквальну позицію, яку ви надали, без помилки чи попередження у відповіді. Вкажіть правдоподібний резервний варіант замість 0,0 та перевірте рендеринг при першому відправленні.

Інтегрований підпис: підпишіть, не залишаючи вашу програму

Ваш клієнт переглядає та підписує свій документ з вашого власного інтерфейсу. Церемонія відкривається у вікні над вашою сторінкою і повертається до вас автоматично після завершення. На стороні сервера нічого нового: ви створюєте конверт як звично, вказуючи redirectUrl, а потім передаєте URL підпису одержувача SDK.

  • • Викличте Certyneo.sign() прямо у вашому обробнику клацання та передайте свій серверний запит через getUrl. await перед sign() виходить із жесту користувача: Safari та Firefox тоді блокують вікно. SDK відкриває його відразу й завантажує його, коли ваша обіцянка розв'язується.
  • • redirectUrl — це канал повернення. Ми перенаправляємо підписавця туди, додаючи certyneo_status (completed або declined) і certyneo_envelope. Завантажте той самий скрипт на цю сторінку повернення: саме він повідомляє вікно портальної сторінки, яка залишилася відкритою позаду.
  • • У вбудованому режимі наші власні кнопки виклику дій приховані. Ваш клієнт ніколи не бачить запрошення створити обліковий запис Certyneo.
  • • Якщо браузер відмовляється відкривати вікно, SDK автоматично перемикається на повнопоточне перенаправлення. Процес для підписавця залишається таким же, а ваша сторінка повернення отримує абсолютно однакові параметри.
  • • Навмисно не існує зворотного виклику «користувач покинув»: стан вікна не читається з вашої сторінки, і такий зворотний виклик запускався б помилково. Підпис, який не надходить, залишається в очікуванні до webhook.
JavaScriptjavascript
// 1. Your server creates and sends the envelope, then hands the browser the
//    recipient's signing URL. Nothing new on the API side:
//      POST /api/v1/envelopes        { …, "redirectUrl": "https://your-app.com/quote/42/signed" }
//      POST /api/v1/envelopes/{id}/send   → recipients[].accessToken
//      signingUrl = "https://certyneo.com/sign/" + accessToken

// 2. On your quote page — load the SDK once:
//      <script src="https://certyneo.com/embed.js"></script>

document.querySelector("#sign").addEventListener("click", () => {
  Certyneo.sign({
    // Called AFTER the window is already open, so no popup blocker ever
    // sees a delay between the click and window.open.
    getUrl: () =>
      fetch("/api/quote/42/signature", { method: "POST" })
        .then((r) => r.json())
        .then((d) => d.signingUrl),

    onCompleted: (e) => showConfirmation(e.envelopeId),
    onDeclined: () => showDeclined(),
    onError: (e) => showError(e),
  });
});

// 3. On https://your-app.com/quote/42/signed — your return page — load the
//    same script and render a short confirmation. It relays the outcome to
//    the portal window behind it, then closes itself.

Подія браузера не є доказом підпису

onCompleted — це сигнал відображення, випущений браузером, тому його можуть підробити з будь-якої консолі. Ніколи не переводьте справу в статус «підписано» на цій основі: використовуйте це для оновлення екрану та покладайтеся на підписаний webhook envelope.completed, отриманий вашим сервером, щоб визначити фактичний статус. Це класична пастка інтеграцій платежів, і вона повторюється тут однаково.

Розроблення на вашому комп'ютері

З тестовим ключем redirectUrl приймає http://localhost (і 127.0.0.1): ви можете весь процес розташувати на своїй машині перед розгортанням. Справжній ключ це відмовляється робити, щоб жоден конверт виробництва не повертав справжнього підписавця на машину, яка не його власна.

Показати церемонію на вашій сторінці

Режим фрейму показує підпис всередині вашого інтерфейсу без вікна. Це потребує додаткового кроку порівняно з режимом вікна: довести, що сайт, який його показуватиме, вам належить. Саме це запобігає тому, щоб третя сторона не вставляла наші церемонії в фрейм для обману ваших клієнтів.

  • • Оголосіть ваш сайт в Налаштування → Інтегрований підпис, потім опублікуйте вказаний DNS запис. Одна точна адреса: поддомен або інший порт вважається іншим сайтом.
  • • При кожному підписі запитайте свіжу URL-адресу за допомогою POST /api/v1/envelopes/{id}/embed-url. Вона несе дозвіл на відображення та діє два години, що відповідає моменту клацання, а не створенню конверта.
  • • Два сценарії не можуть проходити в межах фрейму: кваліфікований підпис, перевірка особистості якого відмовляється бути вставленою в фрейм, та оплата при підписі. В обох випадках підписувач перенаправляється до повного вікна.
  • • Напис «Запустило Certyneo» зникає з фрейму починаючи з тарифу Business. Сам режим фрейму включено вже з тарифу Standard.
JavaScriptjavascript
// Mode cadre : la cérémonie s'affiche DANS votre page.
//
// 1. Déclarez votre site une fois pour toutes dans Réglages → Signature
//    intégrée, et publiez l'enregistrement DNS qu'on vous y donne.
//
// 2. À chaque signature, votre serveur demande une URL fraîche. Elle porte
//    l'autorisation qui permet au navigateur d'afficher la cérémonie chez
//    vous, et vaut deux heures :
//
//      POST /api/v1/envelopes/{id}/embed-url
//      { "origin": "https://portail.exemple.fr" }
//      -> { "signingUrl": "…", "expiresAt": "…" }

Certyneo.sign({
  mode: "iframe",
  el: "#zone-signature",        // sélecteur ou nœud de votre page

  getUrl: () =>
    fetch("/api/devis/42/signature", { method: "POST" })
      .then((r) => r.json())
      .then((d) => d.signingUrl),

  onCompleted: (e) => afficherConfirmation(e.envelopeId),
  onDeclined: () => afficherRefus(),
});

// Le cadre parle à votre page par postMessage — pas besoin de page de retour,
// contrairement au mode fenêtre.

Отримати підпис без відправлення жодного електронного листа

Портал, який відображає церемонію в себе, часто не потребує нашого запрошення: воно приходить поруч з його власним маршрутом і пропонує рахунок клієнту, який його не хоче. Встановіть значення NONE для каналу сповіщення одержувача, і йому більше нічого не буде надіслано — ви сам приведете його на його підпис.

  • • Налаштування встановлюється за одержувачем, а не за конвертом: ви можете заглушити клієнта, якого ви розміщуєте, і зберегти електронний лист для зовнішнього контрпідписувача, у якого немає портала.
  • • Це зарезервовано для підписувачів та затверджувачів, єдиних, кому у вас є посилання для передачі. Ви читаєте його у відповіді на створення та відправлення, або ви запитуєте свіже URL в момент натискання POST /api/v1/envelopes/{id}/embed-url.
  • • Автоматичні повторні надсилання припиняються самі по собі для цього одержувача: ми йому ніколи не писали, ми не починаємо з повторного надсилання. Інші одержувачі продовжують отримувати повторні надсилання в звичайному режимі.
  • • Сертифікат підпису його згадує, одержувач за одержувачем. Досьє доказів, яке мовчало б там, залишило б враження, що цей підписувач отримав від нас запрошення, яке ніколи не існувало.
JSONjson
POST /api/v1/envelopes

{
  "subject": "Mandat de gestion",
  "documentIds": ["doc_8f2c1a4b9e7d"],
  "recipients": [
    {
      "email": "client@exemple.fr",
      "name": "Camille Client",
      "role": "SIGNER",
      "notificationChannel": "NONE"
    },
    {
      "email": "notaire@exemple.fr",
      "name": "Maître Notaire",
      "role": "SIGNER"
    }
  ]
}

// La réponse rend le lien de chaque signataire :
//
//   "recipients": [
//     { "email": "client@exemple.fr",  "accessToken": "…",
//       "notificationChannel": "NONE"  },
//     { "email": "notaire@exemple.fr", "accessToken": "…",
//       "notificationChannel": "EMAIL" }
//   ]
//
// Le client ne reçoit rien : vous l'emmenez sur sa signature depuis votre
// portail. Le notaire, lui, reçoit son invitation comme d'habitude.

Показувати ім'я вашого клієнта як відправника

За замовчуванням підписувач читає ім'я власника ключа API. Якщо ви підписуєте документи кількох компаній за допомогою одного ключа, передайте поле sender під час створення конверта: сторінка підпису та листи запрошення та нагадування будуть показувати ім'я відповідної компанії.

  • • Зарезервовано для плану Business і вище. На нижчому плані створення відхиляється замість того, щоб дозволити підписувачу побачити інше ім'я, ніж очікується.
  • • Ім'я є відображенням: сертифікат та аудит зберігають справжнього відправника, і листи завжди надсилаються від Certyneo.
  • • Адреса необов'язкова. Без неї підписувач бачить лише ім'я, ніколи адресу власника ключа.
JSONjson
POST /api/v1/envelopes

{
  "subject": "Devis 2026-118",
  "documentIds": ["doc_8f2c1a4b9e7d"],
  "recipients": [
    { "email": "client@exemple.fr", "name": "Camille Client", "role": "SIGNER" }
  ],
  "sender": {
    "name": "1.2.3. Panneaux Solaires",
    "email": "devis@123-panneaux-solaires.fr"
  }
}

Аутентифікація

Кожен виклик несе ключ API в заголовку Authorization. Ключі генеруються з Параметрів → Ключі API й показуються лише один раз.

HTTPhttp
GET /api/v1/account/me HTTP/1.1Host: certyneo.com
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

# 200 OK
{ "data": { "id": "usr_…", "email": "you@example.com", "plan": "BUSINESS", "environment": "live" } }
  • • Формат: sk_live_… в продакшені, sk_test_… у пісочниці. Заголовок: Authorization: Bearer <ключ>.
  • • Области: envelopes, documents, webhooks, seals — в режимі читання (:read) або запису (:write). Запис передбачає читання; область * надає всі права.
  • • Ключі sk_test_ створюють ресурси в пісочниці, виключені з квоти й тарифікації. Отримувачу не надсилається справжній лист, якщо тільки його адреса не збігається з email облікового запису відправника — зручно для тестування всього процесу на собі.
  • • Помилки: 401 недійсний ключ, 403 недостатня область, 429 перевищена межа пропускної здатності, 402 досягнута місячна квота.

Форма відповідей

Момент, про який варто знати перед написанням вашого клієнта: колекції обгорнуті в об'єкт data, тоді як одиничні ресурси повертаються пласко. Читання response.data.data на одиничному ресурсі повертає undefined.

Колекція — підписанаjson
// GET /api/v1/envelopes
// Collections are WRAPPED in a "data" array.
{
  "data": [
    { "id": "env_abc123", "subject": "Contrat", "status": "SENT" }
  ]
}
Один ресурс — плоскоjson
// GET /api/v1/envelopes/{id}
// Single resources are returned FLAT — no "data" envelope.
{
  "id": "env_abc123",
  "subject": "Contrat",
  "status": "COMPLETED",
  "recipients": [ /* … */ ]
}

Ліміти пропускної здатності

Ліміти гарантують стабільну якість обслуговування для всіх клієнтів. Якщо вам потрібно більше, зв'яжіться з нами.

  • • 100 запитів на хвилину на API ключ
  • • Виділення допускається до 200 запитів менше ніж за 10 секунд
  • • Відповідь 429 із заголовком Retry-After, який вказує затримку в секундах

Йти далі