Вступ
API Verteco це REST поверх HTTPS. Запит і відповідь мають формат JSON (UTF-8). Почніть зі створення облікового запису, потім API-токена, і зробіть перший виклик протягом хвилини. Усі шляхи вказано відносно базової URL-адреси нижче.
Повне тестове середовище (sandbox) доступне на test.peppol.verteco.digital. Воно поводиться так само, як продуктивне середовище, і додатково пропонує тестові інструменти (вебхук Фінансової адміністрації Словаччини (Finančná správa, FS), верифікаційний токен (Verifikačný údaj), видалення компанії) та симульований вибір постачальника замість порталу FS (VPDS).
- Base URL
https://peppol.verteco.digital/api/v1- Версія
- v1 (у шляху). Зворотно несумісні зміни виходитимуть під новою версією.
- Протокол
- HTTPS only · TLS 1.2+ · TLS A+
- Формат
- application/json (UTF-8)
- Автентифікація
- cookie-сесія (портал) або Bearer-токен (server-to-server)
- Часові мітки
- ISO-8601 (UTC), напр. 2026-06-03T09:40:27Z
Сертифікований AP
Справжній Peppol Access Point (Seat ID PSK001128), а не реселер. Ми пройшли тести відповідності OpenPeppol (19/19) і працюємо в продуктивному режимі.
Валідні документи
Серверна валідація EN 16931 + Peppol BIS 3.0 Schematron кожного отриманого ТА відправленого документа. Документ можна перевірити й заздалегідь: публічний валідатор працює на /validator (і як API на POST /api/v1/public/peppol-validate); помилки повертаються з конкретним правилом (напр. BR-CO-15).
Multi-tenant
Один обліковий запис і один токен для N компаній, ідеально для SaaS, ERP і бухгалтерів.
SK TDD автоматично
Податковий звіт (corner-5 / TDD) до Фінансової адміністрації (FS) ми генеруємо та надсилаємо за Вас.
openapi-generator. Він охоплює як API порталу, так і SAPI-SK.Швидкий старт
Обліковий запис і API-токен Ви створюєте в порталі (через браузер). Далі інтеграція працює виключно через API-токен. Вашому застосунку не потрібно обробляти реєстрацію, вхід чи паролі.
- 1
Створіть обліковий запис у порталі
Зареєструйтеся за допомогою електронної пошти і підтвердьте її за посиланням з електронного листа. - 2
Згенеруйте API-токен
У порталі перейдіть до API tokeny → Vytvoriť (API-токени → Створити). Токенvpt_…показується лише один раз. Зберігайте його надійно. - 3
Зробіть перший виклик
Використайте токен у заголовкуAuthorization:javascriptconst res = await fetch('https://peppol.verteco.digital/api/v1/companies', { headers: { Authorization: 'Bearer vpt_8f2a…' }, }); const companies = await res.json();
Тестове середовище (sandbox)
Окрім SAPI mock sandbox (нижче), ми також підтримуємо повнофункціональне тестове середовище, повну копію цього порталу з окремими даними, де можна випробувати весь процес (реєстрація → компанія → відправлення → отримання → сповіщення) від початку до кінця без жодного впливу на продуктивне середовище.
- Реєстрація
- без листа з підтвердженням; обліковий запис можна використовувати одразу
- Схвалення компанії
- автоматичне, безпосередньо в інтерфейсі або через API; немає вибору постачальника на порталі Фінансової адміністрації Словаччини (Finančná správa, FS) і немає входу на портал ФА; одразу після створення компанії з номером платника ПДВ (IČ DPH) Ви можете як відправляти, так і отримувати
- Реєстрація в мережі
- автоматична, до тестової мережі Peppol. Зверніть увагу на два рівні ідентифікатора: API і портал використовують той самий формат, що й продуктивне середовище (
peppolParticipantId = 0245:<цифри DIČ>, де DIČ це словацький податковий ідентифікаційний номер; Ваш інтеграційний код не змінюється); у тестових SMP/SML компанія технічно реєструється як9950:SK<DIČ>, оскільки схема 0245 вимагає верифікаційного коду Фінансової адміністрації, якого в тестовому середовищі не існує. У продуктивному середовищі0245:<цифри DIČ>реєструється в робочій мережі Peppol лише після вибору постачальника на порталі ФА (вхід через eID або за обліковими даними) - Валідація
- реальна: правила EN 16931 + Peppol BIS 3.0, ті самі, що й у продуктивному середовищі
- Доставка
- реальна, через тестову мережу Peppol (AS4, тестовий сертифікат, тестові SML/SMP): отримувач, зареєстрований у тестовій мережі, отримує рахунок як отриманий (включно з електронним листом, PDF і вебхуком); у робочу мережу нічого не потрапляє
- Підтвердження доставки (MLS)
- реальне підтвердження MLS з тестової мережі
- Електронні листи
- справді надсилаються (на адреси, які Ви вводите), з префіксом
[TEST] - Ціна
- безкоштовно, без обмежень для тестування
Усе, що працює тут, працює і там: портал, REST API, SAPI-SK 1.0, плагіни для інтернет-магазинів і вебхуки. Достатньо змінити домен у Вашій інтеграції на test.peppol.verteco.digital і використовувати токени, створені в тестовому середовищі. Ідеально для розробки інтеграції, CI-тестів і навчання бухгалтерів перед продуктивним запуском.
Примітка: захист периметра (edge) тестового домену блокує загальні заголовки User-Agent: Python-urllib і User-Agent: Java/1.8.x (стандартний User-Agent HttpsURLConnection у Java 8) відповіддю HTTP 403 "error code: 1010" ще до того, як запит дійде до нашого API; продуктивний домен peppol.verteco.digitalїх пропускає. Встановіть власний User-Agent: у Java або прапорцем JVM -Dhttp.agent=my-app/1.0 (без зміни коду; Java додає "Java/1.8", і результат "my-app/1.0 Java/1.8.0_xxx" проходить, блокується лише заголовок, що починається з "Java/1.8"), або на з'єднанні через conn.setRequestProperty("User-Agent", "my-app/1.0"). Поширені клієнти (requests, httpx, Java 11+, Apache HttpClient, okhttp, axios, Go, PHP, curl) працюють без змін.
Чому компанії схвалюються автоматично
Фінансова адміністрація не має тестового середовища для порталу VPDS: вибір постачальника на vpds.financnasprava.sk працює лише в продуктивному середовищі та перевіряється входом на портал ФА (eID або облікові дані порталу), тому в продуктивному середовищі Ви не можете «обрати» довільну компанію, яка не є Вашою. Щоб Ви все ж могли протестувати свою інтеграцію, у тестовому середовищі ми симулюємо цей крок: кожна створена Вами компанія схвалюється автоматично (без вибору у FS), тож Ви можете налаштувати як відправника, так і отримувача та пройти весь процес.
Для тестування вебхуків FS (вибір постачальника) ми маємо власний аналог інструменту Фінансової адміністрації: test.peppol.verteco.digital/sandbox-nastroje. Там можна згенерувати валідний верифікаційний токен (Verifikačný údaj) у стилі FS і надіслати повний вебхук на Ваш endpoint, точно так, як це робить портал FS під час реального вибору. Компанії, створені для тестування, натомість можна зняти з реєстрації (з порталу та з тестового SMP), саме через відсутність тестового режиму на боці Фінансової адміністрації.
Автентифікація
Ваша інтеграція автентифікується за допомогою API-токена в заголовку Authorization: Bearer vpt_…. Токен Ви створюєте в порталі (API-токени); він має формат vpt_ + 40 hex-символів, ми зберігаємо лише його SHA-256 хеш, і він має той самий доступ, що і Ваш обліковий запис. Перевірте його через /auth/me:
curl https://peppol.verteco.digital/api/v1/auth/me -H 'Authorization: Bearer vpt_8f2a…'
# 200 → { "id": "…", "email": "vy(at)firma.sk" } (token works)Якщо токен відсутній або недійсний, API повертає:
// 401 Unauthorized
{ "error": "unauthorized", "message": "Authentication required" }portal_session, JWT, 7 днів); для інтеграції server-to-server вона Вам не потрібна. Публічними без автентифікації є /ping, /openapi.json та endpoint-и під /public/* (перевірка peppol-check, валідатор peppol-validate, докладніше в розділі Публічні інструменти, і стан сервісу через status); усе інше вимагає сесії або Bearer-токена.Конвенції та формати
| Тип | Формат | Приклад |
|---|---|---|
id | UUID (string) | 08dd6c1e-… |
часові мітки | ISO-8601 Instant (UTC) | 2026-06-03T09:40:27Z |
issueDate | дата (YYYY-MM-DD) | 2026-06-03 |
totalAmount | десяткове число | 120.00 |
відсутні значення | null (а не пропущене поле) | "dic": null |
Пагінація та ідемпотентність
/companies і /companies/{id}/documents підтримують опціональні ?page&limit (відповідь залишається JSON-масивом; загальна кількість міститься в заголовках X-Total-Count / X-Total-Pages). Без параметрів вони повертають увесь масив, документи відсортовані за createdAt за спаданням; /tokens завжди повертає увесь масив. Заголовок Idempotency-Key підтримує національний інтерфейс SAPI-SK на POST /sapi/document/send; для програмного відправлення використовуйте саме його.Помилки
Помилки мають єдину структуру з машинозчитуваним кодом error. Помилки валідації додають мапу fields (перша помилка для кожного поля).
// business error
{ "error": "invalid_credentials", "message": "Invalid email or password" }
// validation error (400); field messages are returned in Slovak ("IČO musí byť 8 číslic" = "IČO must be 8 digits")
{ "error": "validation_failed", "message": "Some fields are invalid",
"fields": { "ico": "IČO musí byť 8 číslic" } }HTTP-статуси
- 200 / 201 / 204
- успіх (OK / Created / No Content)
- 400
- недійсні вхідні дані (див. error / fields)
- 401
- відсутня або недійсна автентифікація
- 403
- недостатньо прав (роль)
- 404
- ресурс не існує або Ви не маєте до нього доступу
- 405
- HTTP-метод не підтримується для цього шляху
- 409
- конфлікт (IČO / електронна адреса вже існує)
- 415
- непідтримуваний Content-Type (XML endpoint-и очікують application/xml)
- 429
- перевищено ліміт запитів (заголовки RateLimit-* і Retry-After, тіло JSON rate_limited)
error. Відповідь без JSON-тіла (HTML або текст, як error code: 1010 зі статусом 403, або 502/504 під час розгортання) надійшла не від API, а від інфраструктури перед ним (захист периметра, шлюз). Типова причина 403/1010: загальний User-Agent бібліотеки (Python-urllib, Java/1.8.x на тестовому домені); рішення описано в розділі Тестове середовище.Повний каталог помилок
| Код | HTTP | Коли |
|---|---|---|
validation_failed | 400 | тіло не пройшло валідацію (див. fields) |
unauthorized | 401 | відсутній або недійсний API-токен |
forbidden | 403 | дія вимагає ролі owner/admin |
company_not_found | 404 | компанія не існує або Ви не є її учасником |
ico_taken | 409 | компанія з таким IČO (реєстраційним номером компанії) вже існує |
ico_immutable | 400 | IČO не можна змінити |
company_dic_missing | 400 | верифікація для відправлення без DIČ компанії (словацького податкового ідентифікаційного номера) |
token_invalid | 400 | верифікаційний токен (Verifikačný údaj, підпис) не збігається |
document_not_found | 404 | документ не існує |
token_not_found | 404 | API-токен не існує / не належить Вам |
rate_limited | 429 | надто багато запитів |
Ліміти запитів (rate limit)
API захищене обмеженням частоти запитів у 60-секундному вікні (на інстанс). Ліміт і залишок квоти повертаються в кожній відповіді через заголовки; при перевищенні API повертає 429 Too Many Requests із Retry-After.
- Звичайні виклики
- динамічний ліміт із великим запасом, на API-токен (або сесію, інакше IP); поточне значення повертається в заголовку RateLimit-Limit
- Auth (/auth/*)
- суворіший ліміт на IP (захист від brute-force; крім /auth/me і /auth/logout)
RateLimit-Limit- ліміт у вікні
RateLimit-Remaining- скільки запитів залишилося
RateLimit-Reset- секунд до скидання вікна
Retry-After- секунд до наступної спроби (при 429)
HTTP/2 429 Too Many Requests
RateLimit-Limit: <limit in the window>
RateLimit-Remaining: 0
RateLimit-Reset: 37
Retry-After: 37
{ "error": "rate_limited", "message": "Too many requests. Slow down." }- Ліміти прив’язані до облікових даних, а не до IP: 300 викликів за хвилину на API-токен (SAPI: на access token), auth-ендпоінти 20 за хвилину на IP та захисний поріг 600 за хвилину на IP для /api/v1. Серверну інтеграцію за однією IP це не зачіпає; вищі ліміти встановлюємо на запит, напишіть очікуваний пік.
- Polling є повноцінним шляхом: GET /sapi/document/sent і /receive з ?since та ?until кожні 1–5 хвилин; вебхуки є доповненням, а не умовою.
- Часові позначки: час відправлення = statusDateTime стану delivered у /sapi/document/sent (підтверджено квитанцією MLS), час отримання = creationDateTime у /sapi/document/receive; час передання повідомлення FS = fsReportedAt (вебхук invoice.reported або поле fsReportedAt у подіях invoice.*); кожен вебхук містить occurredAt та eventId.
- PDF: через API повертаємо HTML для друку (…/html, портал ?format=html), з якого PDF друкується у браузері або headless Chrome; окремого PDF-ендпоінта немає.
- C#/.NET та інші мови: згенеруйте клієнт з OpenAPI (NSwag, Kiota, openapi-generator); власного пакета NuGet ми не постачаємо.
API-токени
Непрозорі (opaque) токени vpt_… для доступу server-to-server. Відкритий текст показується лише один раз при створенні. Збережіть його. Ми зберігаємо лише SHA-256 хеш і 12-символьний префікс для відображення.
/tokenssession / tokenСписок Ваших активних токенів (без секрету), createdAt за спаданням.
/tokenssession / tokenСтворює токен; повертає відкритий текст (лише один раз).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
name | string | так | назва токена, макс. 128 |
curl -X POST https://peppol.verteco.digital/api/v1/tokens -b cookies.txt \
-H 'Content-Type: application/json' -d '{"name":"moja-appka"}'
# 201 Created
{ "id":"…","name":"moja-appka","token":"vpt_8f2a…","prefix":"vpt_8f2a3b…","createdAt":"…" }/tokens/{id}session / tokenВідкликає токен. Повертає 204.
Помилки: token_not_found (404)
Компанії
Компанії, ідентифіковані за реєстраційним номером (IČO) / номером платника ПДВ (IČ DPH), якими Ви керуєте. Доступ залежить від членства: Ви бачите лише компанії, учасником яких є. Творець компанії стає її owner.
/companiessession / tokenСписок компаній, учасником яких Ви є (з Вашою роллю).
/companiessession / tokenДодає компанію; Ви стаєте її owner, status = pending_verification.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
ico | string | так | рівно 8 цифр |
dic | string | так | ІПН ПДВ у форматі SK + 10 цифр (напр. SK2121358349); неплатник ПДВ надсилає лише 10 цифр DIČ, SK додаємо ми |
legalName | string | так | юридична (комерційна) назва, макс. 500 |
registeredAddress | string | ні | адреса зареєстрованого офісу, макс. 1000 |
curl -X POST https://peppol.verteco.digital/api/v1/companies \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"ico":"53412834","dic":"SK2121358349","legalName":"Verteco digital services, s. r. o."}'
# 201 Created
{ "id":"08dd…","ico":"53412834","dic":"SK2121358349","legalName":"…",
"registeredAddress":null,"peppolParticipantId":null,
"status":"pending_verification","role":"owner","createdAt":"2026-06-03T09:40:27Z" }Помилки: ico_taken (409) · validation_failed (400)
/companies/{id}session / tokenДеталі компанії (Ви маєте бути учасником).
/companies/{id}owner / adminОновлює компанію. IČO незмінне (має дорівнювати наявному значенню).
Помилки: forbidden (403) · ico_immutable (400) · company_not_found (404)
Поле status
pending_verification- після створення; відправлення ще не розблоковано
active- верифікована, відправлення розблоковано
Роль учасника
owner- творець компанії (повний доступ)
admin- адміністратор (редагування, вебхуки, верифікація)
member- учасник (читання)
viewer- лише читання
owner, так і admin (менеджер компанії).Верифікація для відправлення (верифікаційний токен, Verifikačný údaj)
Перед відправленням компанію необхідно верифікувати за допомогою верифікаційного токена (Verifikačný údaj, VÚ), підписаного токена, який видає Фінансова адміністрація Словаччини (Finančná správa, FS). Після успішної верифікації status компанії змінюється на active і відправлення розблоковується.
/companies/{id}/verificationowner / adminСамостійна верифікація верифікаційного токена (Verifikačný údaj). У разі успіху встановлює status на active.
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
token | string | так | VÚ = hex-підпис (prod/pPFS 1024 hex, test/tPFS 768 hex) |
curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/verification \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"token":"<1024-hex VÚ>"}'
# 200 OK
{ "companyId":"08dd…","status":"active","sendingVerified":true,
"verificationMethod":"self","verifiedAt":"2026-06-15T…Z" }Помилки: company_dic_missing (400) · token_invalid (400) · forbidden (403)
Документи
Журнал документів Peppol (отриманих і відправлених) для компанії. Він наповнюється в міру того, як рахунки проходять через Access Point. Залежить від членства в компанії, відсортовано за createdAt за спаданням.
/companies/{id}/documentssession / tokenСписок документів компанії. Опціональний фільтр ?direction=sent|received.
curl 'https://peppol.verteco.digital/api/v1/companies/{id}/documents?direction=received' \
-H 'Authorization: Bearer vpt_8f2a…'
# 200 OK
[ { "id":"…","direction":"received","peppolMessageId":"…","docTypeId":"…",
"senderId":"0088:7300010000001","receiverId":"0245:2121358349",
"invoiceNumber":"2026001","issueDate":"2026-06-03",
"currency":"EUR","totalAmount":120.00,"status":"received","createdAt":"…" } ]/companies/{id}/documents/{docId}session / tokenДеталі одного документа.
Помилки: document_not_found (404)
/companies/{id}/documents/{docId}/downloadsession / tokenОкремий HTML рахунка для друку. ?inline=1 → відображає в браузері, інакше завантажує.
Повертає text/html із Content-Disposition, де файл має назву faktura-<číslo>.html (číslo = номер рахунка).
SAPI-SK 1.0 (національний інтерфейс)
SAPI-SK це стандартизований національний REST-інтерфейс між клієнтською/ERP-системою та Access Point (sapi-sk.sk). Ми реалізуємо його повністю. Це означає, що Ви не залежите від нашої пропрієтарної форми API і пишете інтеграцію один раз для будь-якого SAPI-SK Access Point.
- Base URL
https://peppol.verteco.digital/sapi- Автентифікація
- OAuth2 client_credentials → короткостроковий access-токен (JWT)
- client_id
- UUID Вашого API-токена (наведений у розділі API-токени / dashboard)
- client_secret
- сам токен
vpt_…з порталу - Версія
- 1.3 (10 операцій: 4× auth, 6× документи)
vpt_, ні сесія). Відкликання API-токена в порталі негайно робить недійсними як /auth/token, так і /auth/renew.Sandbox (пробне середовище)
Хочете випробувати SAPI-SK без реєстрації і без жодного ризику? Використайте публічні облікові дані sandbox. Sandbox валідує запити точно так, як продуктивне середовище, але ніколи нічого не надсилає в мережу Peppol і не працює з реальними даними; він повертає реалістичні mock-відповіді. Ідеально для розробки, CI та онбордингу інтеграції.
- client_id
sandbox- client_secret
sandbox- send
- повна валідація контракту + mock 202 (ніщо не доставляється)
- receive
- 1 зразковий документ
sandbox-doc-0001для тестування парсингу та acknowledge
# 1) sandbox token (no registration required)
curl -X POST https://peppol.verteco.digital/sapi/auth/token \
-H 'Content-Type: application/json' \
-d '{ "client_id": "sandbox", "client_secret": "sandbox",
"grant_type": "client_credentials" }'
# 2) mock send: it is validated, but NOTHING is actually delivered
curl -X POST https://peppol.verteco.digital/sapi/document/send \
-H 'Authorization: Bearer <sandbox access_token>' \
-H 'X-Peppol-Participant-Id: 0245:0000000000' \
-H 'Content-Type: application/json' \
-d '{ "metadata": { "documentId": "TEST-1",
"documentTypeId": "urn:…::Invoice##…::2.1",
"senderParticipantId": "0088:sandbox-sender",
"receiverParticipantId": "0088:sandbox-receiver" },
"payload": "<Invoice>…</Invoice>", "payloadFormat": "XML" }'
# 202 { "providerDocumentId": "sandbox-…", "status": "ACCEPTED", … }
# 3) sample inbox + detail of the sample document
curl https://peppol.verteco.digital/sapi/document/receive \
-H 'Authorization: Bearer <sandbox access_token>'
curl https://peppol.verteco.digital/sapi/document/receive/sandbox-doc-0001 \
-H 'Authorization: Bearer <sandbox access_token>'client_id/client_secret з порталу (нижче).Автентифікація
/sapi/auth/tokenclient_credentialsОбмінює client_id + client_secret на access-токен (15 хв) і refresh-токен (30 днів). Збережіть токен і використовуйте його всі 15 хвилин: запит нового токена при кожному виклику є зайвими витратами (ліміт запитів враховує і виклики /auth/token).
curl -X POST https://peppol.verteco.digital/sapi/auth/token \
-H 'Content-Type: application/json' \
-d '{ "client_id": "<token UUID>", "client_secret": "vpt_8f2a…",
"grant_type": "client_credentials" }'
# 200 OK
{ "access_token": "eyJhbGciOi…", "token_type": "Bearer",
"expires_in": 900, "refresh_token": "eyJhbGciOi…" }Помилки: SAPI-AUTH-001 (401) · SAPI-AUTH-003 (401: IP поза списком дозволених адрес ключа) · SAPI-VAL-001 (400)
/sapi/auth/token/statusBearer (access)Дійсність і термін дії access-токена; should_refresh = true, коли залишається менше 3 хв.
/sapi/auth/renewrefresh tokenВидає новий access + refresh-токен. Не вдається, якщо базовий API-токен було відкликано.
// body
{ "refresh_token": "eyJhbGciOi…" }/sapi/auth/revoke–Завжди повертає успіх (RFC 7009). Постійний kill switch: відкликання API-токена в порталі.
Відправлення документа
/sapi/document/sendBearer (access)Відправляє бізнес-документ Peppol (UBL / BIS 3.0) отримувачу через наш Access Point. Відправлення працює за принципом fail-closed: компанія має мати верифікований верифікаційний токен (Verifikačný údaj).
Обов'язкові заголовки:
| Заголовок | Опис |
|---|---|
Authorization | Bearer <access_token> |
X-Peppol-Participant-Id | учасник, від імені якого Ви відправляєте (напр. 0245:2121358349, цифри DIČ (словацького податкового ідентифікаційного номера) без префікса "SK") |
Idempotency-Key | унікальний ключ на одне відправлення; повторний виклик повертає початковий результат і ніколи не доставляє двічі. Виняток: якщо першу спробу відхилено ще до відправлення (отримувача немає в мережі Peppol, помилка валідації, неповний запит), той самий ключ виконає відправлення знову, тож «виправити й надіслати повторно» працює під тим самим номером рахунку |
curl -X POST https://peppol.verteco.digital/sapi/document/send \
-H 'Authorization: Bearer eyJ…' \
-H 'X-Peppol-Participant-Id: 0245:2121358349' \
-H 'Idempotency-Key: 7b1f0e2a-…' \
-H 'Content-Type: application/json' \
-d '{ "metadata": {
"documentId": "INV-2026-001",
"documentTypeId": "urn:…::Invoice##…::2.1",
"processId": "urn:…:bis:billing:3.0",
"senderParticipantId": "0245:2121358349",
"receiverParticipantId": "0088:7300010000001",
"creationDateTime": "2026-06-17T10:00:00Z" },
"payload": "<Invoice …>…</Invoice>",
"payloadFormat": "XML" }'
# 202 Accepted
{ "providerDocumentId": "…", "status": "ACCEPTED",
"receivedAt": "2026-06-17T10:00:01Z", "timestamp": "…" }
# when status is "REJECTED", the response also carries a "detail" field
# with the rejection reason (validation rules, e.g. BR-CO-15)metadata це маршрутизаційні та технічні поля: documentId це Ваш внутрішній ідентифікатор, а не номер рахунка. Бізнес-дані (номер рахунка cbc:ID, дата виставлення, термін оплати, дата постачання, валюта, сума) беруться безпосередньо з UBL payload; нічого з цього Ви не надсилаєте в metadata, і UBL завжди є джерелом істини для відображення в порталі та для вебхуків.Помилки: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400) · SAPI-PROC-001 (502) · SAPI-PROC-002 (503) · SAPI-PROC-500 (500: не повторюйте, повідомте correlation_id)
202, а вердикт міститься в тілі (status ACCEPTED або REJECTED). Якщо Ви хочете, щоб HTTP-код також ніс вердикт, надішліть заголовок Prefer: handling=strict (RFC 7240): синхронна відмова тоді повертається як 422 з конвертом помилки SAPI (SAPI-VAL-002 при помилці валідації, SAPI-RES-003, коли одержувачу неможливо доставити; details[] містять providerDocumentId і detail), а відповідь має заголовок Preference-Applied: handling=strict. ACCEPTED не змінюється. Перед передачею точці доступу ми виконуємо той самий пошук SML/SMP, що й вона. Одержувач, якого взагалі немає в мережі Peppol, означає ACCEPTED з undeliverable: true: ми прийняли документ і повідомляємо його Фінансовій адміністрації незалежно від доставки (§ 85o ч. 11, FS FAQ 9/DPH/2025/IM приклад 9), але нікому він не доставляється; у GET /sapi/document/sent він має статус undeliverable, вебхук отримує invoice.undeliverable, e-mail нікому не надсилається, а той самий Idempotency-Key після реєстрації одержувача надсилає знову. Одержувач, який є в мережі, але не публікує тип документа, одразу отримує REJECTED без спроби доставки. retrying: true при ACCEPTED означає, що перша спроба доставки не вдалася (наприклад, тимчасово недоступний SMP) і точка доступу повторює її сама, зазвичай протягом 20 хвилин; detail містить причину, а остаточний вердикт надходить через GET /sapi/document/sent або вебхук./sapi/document/validateBearer (access)Перевіряє документ без відправлення: ті самі правила EN 16931 + Peppol BIS 3.0, які точка доступу застосовує перед відправленням. Нічого не зберігається і не відправляється; працює й із sandbox-токеном. Тіло = JSON-пара { payload, payloadFormat } як у /document/send або безпосередньо XML (Content-Type: application/xml). Ліміт 10 МБ.
curl -X POST https://peppol.verteco.digital/sapi/document/validate \
-H 'Authorization: Bearer eyJ…' \
-H 'Content-Type: application/xml' \
--data-binary @rakhunok.xml
# 200 OK
{ "valid": false,
"errors": [ "BR-CO-15: Invoice total amount with VAT (BT-112) = … " ],
"warnings": [],
"checkedAt": "2026-09-10T12:00:00Z" }Помилки: SAPI-AUTH-002 (401) · SAPI-VAL-001 (400: порожнє тіло, недійсний JSON, payloadFormat не XML, > 10 МБ) · SAPI-SYS-002 (502: валідатор тимчасово недоступний, повторіть)
Отримання документів
/sapi/document/receiveBearer (access)Список отриманих документів (найстаріші першими); метадані також містять invoiceNumber, тож документ можна ідентифікувати без завантаження payload. Query: ?pageToken, ?limit (макс. 200), ?status (received / acknowledged; без урахування регістру, будь-яке інше значення повертає помилку SAPI-VAL-001), ?invoiceNumber (точна відповідність cbc:ID), ?since і ?until (ISO-8601 instant; вікно за часом отримання, напр. документи за останні 5 днів, масове завантаження для зовнішнього архівування або відновлення бухгалтерського обліку), ?deliveryDateFrom і ?deliveryDateTo (ISO-8601 date; фільтр за датою постачання, вказаною в документі). Заголовок X-Peppol-Participant-Id обов'язковий.
// 200 OK
{ "documents": [ { "documentId":"…","documentTypeId":"…",
"senderParticipantId":"0088:…","receiverParticipantId":"0245:…",
"creationDateTime":"2026-06-17T…Z" } ],
"nextPageToken": "50" }/sapi/document/receive/{documentId}Bearer (access)Деталі включно з payload (сирий XML, точно так, як він надійшов через Peppol).
Помилки: SAPI-RES-001 (404) · SAPI-RES-002 (404: payload не архівовано)
/sapi/document/receive/{documentId}/acknowledgeBearer (access)Підтверджує, що Ваша система прийняла документ. Ідемпотентний.
/sapi/document/receive/{documentId}/xmlBearer (access)Архівне посилання (metadata.links.xml): сам діловий документ як XML-файл, той самий вміст, що й payload у деталях.
/sapi/document/receive/{documentId}/htmlBearer (access)Архівне посилання (metadata.links.html): загальне придатне для друку відображення рахунку (HTML).
/sapi/document/receive/{documentId}/pdfBearer (access)Архівне посилання (metadata.links.pdf): PDF документа. Якщо постачальник вклав у XML власний PDF рахунку (BT-125), ви отримаєте цей оригінал; інакше PDF, згенерований на вимогу зі збереженого XML (PDF не зберігається). Заголовок X-Verteco-Pdf-Source: supplier | generated. 404 SAPI-RES-002 після видалення вмісту, 503 коли рендерер недоступний (повторіть пізніше або використайте /html).
/sapi/document/receive/{documentId}/attachments/{index}Bearer (access)Архівне посилання (metadata.links.attachments[].url): байти одного вкладення, вбудованого в документ, напр. PDF-оригінал постачальника. Примусове завантаження.
/sapi/document/receive/{documentId}/public-linkBearer (access)Посилання без входу (необов’язково): видає НОВИЙ випадковий ключ для документа ({"rotate":true} замінює наявний). Повертає url (сторінка), xmlUrl, htmlUrl, pdfUrl та expiresAt; ключ показується лише раз. У компанії має бути увімкнено «завантаження без входу» (інакше 403 SAPI-AUTH-004). DELETE відкликає його.
Стан відправлених документів
/sapi/discovery?receiverId=0245:2121358349Попередня перевірка перед відправленням: чи зареєстровано отримувача в мережі Peppol і які типи документів він може отримувати? Той самий SML/SMP lookup, який виконує Access Point; receiverId приймає Peppol ID, номер платника ПДВ (IČ DPH) або сам DIČ. Відповідь: {registered, participantId, smp, documentTypes, checkedAt}. Заголовок X-Peppol-Participant-Id тут не потрібен.
/sapi/document/sentBearer (access)Стан доставки відправлених документів: pending (передається мережі) → submitted → delivered / rejected (підтверджено підтвердженням доставки (MLS) від AP отримувача); failed = транспортна помилка (повторна спроба з тим самим Idempotency-Key відправляє знову). Query: ?pageToken, ?limit, ?status (pending / submitted / sent / delivered / rejected / failed; без урахування регістру, будь-яке інше значення повертає помилку SAPI-VAL-001), ?invoiceNumber (точна відповідність cbc:ID: стан конкретного рахунка одним викликом), ?since і ?until (ISO-8601 instant; часове вікно), ?deliveryDateFrom і ?deliveryDateTo (ISO-8601 date; фільтр за датою постачання).
// 200 OK
{ "documents": [ {
"documentId": "…",
"receiverParticipantId": "0245:1084695645",
"peppolMessageId": "befc9112-…",
"status": "delivered",
"statusDateTime": "2026-07-09T14:52:31Z",
"creationDateTime": "2026-07-09T14:52:12Z" } ],
"nextPageToken": null }Помилки: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400: недійсний since)
Пакетне відправлення
/sapi/document/batchBearer (access)До 100 документів в одному виклику. Кожен елемент проходить повну логіку одиночного відправлення (ідемпотентність через itemId + idempotencyKey, резервування, submit, вердикт) і повертає власний результат; збій одного елемента не зупиняє інші. Елементи обробляються послідовно; невдалі елементи повторюйте з тим самим idempotencyKey.
// request
{ "documents": [ {
"itemId": "fa-2026-001",
"idempotencyKey": "fa-2026-001",
"metadata": { "documentId": "2026001", "documentTypeId": "…", "processId": "…",
"senderParticipantId": "0245:2121358349", "receiverParticipantId": "0245:1084695645" },
"payload": "<Invoice …>", "payloadFormat": "XML" } ] }
// 202 Accepted
{ "total": 2, "accepted": 1, "rejected": 1, "failed": 0,
"results": [
{ "itemId": "fa-2026-001", "ok": true, "providerDocumentId": "…", "status": "ACCEPTED" },
{ "itemId": "fa-2026-002", "ok": false, "errorCode": "SAPI-AUTH-003", "errorMessage": "…" } ] }Помилки: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400: порожній або надто великий список)
Модель помилок
Усі помилки SAPI мають єдину обгортку з категорією, стабільним кодом, прапорцем retryable і correlation_id для служби підтримки.
{ "error": {
"category": "AUTH",
"code": "SAPI-AUTH-001",
"message": "Invalid client credentials.",
"retryable": false,
"correlation_id": "b4191dfc-…" } }Сповіщення та вебхуки
Про отриманий рахунок ми можемо повідомити компанію електронною поштою або вебхуком (POST на Вашу URL-адресу). Доставка надійна (durable): сповіщення зберігається у вихідній черзі та доставляється асинхронно (тайм-аут 15 с); у разі збою ми повторюємо до 8 разів з експоненційною затримкою (30 с → макс. 1 год), потім dead-letter. Отже, збій Вашого сервера не втрачає сповіщення; ми доставимо його при наступній спробі. Захист від SSRF блокує loopback/локальні адреси; URL вебхука має бути публічною.
/companies/{id}/notificationssession / tokenНалаштування сповіщень: { webhookUrl, notificationEmail, hasSecret }.
/companies/{id}/notificationsowner / adminВстановлює обидва канали (порожній рядок вимикає відповідний канал).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
webhookUrl | string | ні | порожньо або http(s) URL, макс. 512 |
notificationEmail | string | ні | дійсна електронна адреса, макс. 256 |
/companies/{id}/webhooksession / tokenКонфігурація вебхука: { url, hasSecret } (без секрету).
/companies/{id}/webhookowner / adminВстановлює URL вебхука (автоматично генерує секрет для підпису, якщо його ще немає).
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
url | string | так | http(s) URL, макс. 512 |
curl -X PUT https://peppol.verteco.digital/api/v1/companies/{id}/webhook \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"url":"https://vas-system.sk/peppol/webhook"}'
# 200 OK { "url":"https://vas-system.sk/peppol/webhook", "hasSecret": true }/companies/{id}/webhookowner / adminВидаляє як URL вебхука, так і секрет. Повертає 204.
/companies/{id}/webhook/secretowner / adminГенерує новий секрет для підпису та повертає його ОДИН РАЗ; збережіть його для перевірки X-Verteco-Signature.
// 200 OK
{ "secret": "vpt_8f2a…" }/companies/{id}/webhook/testowner / adminСинхронно надсилає тестове сповіщення (подія webhook.test, підписана, із захистом від SSRF) на збережену URL і повертає, ЩО було надіслано і ЩО повернулося. Те саме запускає кнопка „Otestovať webhook“ (Тестувати вебхук) у деталях компанії.
// 200 OK
{
"sent": { "url": "https://vas-system.sk/peppol/webhook", "event": "webhook.test",
"signed": true, "payload": "{…}" },
"received": { "status": 200, "body": "OK", "durationMs": 142, "error": null }
}
// 400 webhook_not_configured if no webhook URL is storedPayload вебхука
Як для отриманого (invoice.received), так і для відправленого (invoice.sent) рахунка ми надсилаємо POST із таким тілом; поле event розрізняє тип.
Ще дві події повідомляють про вердикт мережі щодо відправленого Вами рахунка: invoice.delivered (Access Point отримувача підтвердив доставку підтвердженням доставки (MLS)) і invoice.rejected (відхилено, або мережею, або під час валідації перед відправленням). Вони містять ідентифікацію документа та компанії (documentId, invoiceNumber, receiverId, peppolMessageId, companyDic, peppolParticipantId), а також status, statusDetail із причиною відхилення та statusDateTime. Якщо перша спроба доставки не вдалася і точка доступу сама її повторює (зазвичай протягом години), документ залишається submitted, а statusDetail починається з префікса network_retrying: ; після доставки стан стає delivered, після відмови rejected з префіксом network_gave_up: . Завдяки їм Вам не потрібно опитувати стан відправлених рахунків.
Подія company.activated надходить, коли клієнт завершує вибір постачальника на порталі (VPDS) Фінансової адміністрації Словаччини (Finančná správa, FS); тіло: event, companyId, companyDic, peppolParticipantId, status, verifiedAt. company.deactivated натомість надходить, коли компанію знімають з реєстрації в мережі (те саме тіло без verifiedAt). company.smp_registered_elsewhere надходить, коли компанія завершила вибір на порталі ФА, але її запис у національному SMP тримає інший провайдер (тіло як у company.activated плюс action: "migration_code_required" і migrateUrl). Порядок дій для партнерів наведено в документації для посередників. Доки клієнт не введе код міграції, мережа доставляє старому провайдеру. Докладніше в посібнику /saas:
{
"event": "invoice.received",
"eventId": "7f1c2d9e-4b1a-4e3d-9c1f-0a2b3c4d5e6f",
"occurredAt": "2026-09-03T15:04:05Z",
"companyId": "08dd…",
"documentId": "…",
"invoiceNumber": "2026001",
"senderId": "0088:7300010000001",
"supplierName": "Dodávateľ s.r.o.",
"receiverId": "0245:2121358349",
"issueDate": "2026-06-03",
"dueDate": "2026-06-17",
"deliveryDate": "2026-06-03",
"currency": "EUR",
"totalAmount": "120.00",
"peppolMessageId": "…",
"companyDic": "SK2121358349",
"peppolParticipantId": "0245:2121358349"
}Поля companyDic і peppolParticipantId ідентифікують компанію, якої стосується подія (важливо для партнерів, які використовують одну URL вебхука для всіх своїх клієнтів).
Вердикт мережі щодо відправленого рахунка:
{
"event": "invoice.delivered", // or "invoice.rejected"
"occurredAt": "2026-09-03T15:04:05Z",
"companyId": "08dd…",
"companyDic": "SK2121358349",
"peppolParticipantId": "0245:2121358349",
"documentId": "…",
"invoiceNumber": "2026001",
"receiverId": "0245:2120049096",
"peppolMessageId": "…",
"status": "delivered", // or "rejected"
"statusDetail": null, // for rejected: the rejection reason
"statusDateTime": "2026-06-03T10:15:42Z"
}Активація компанії після вибору постачальника на порталі FS (VPDS):
{
"event": "company.activated", // company.deactivated has the same body without verifiedAt
"occurredAt": "2026-09-03T15:04:05Z",
"companyId": "08dd…",
"companyDic": "SK2121358349",
"peppolParticipantId": "0245:2121358349",
"status": "active",
"verifiedAt": "2026-06-03T10:02:11Z"
}Назва події також передається в заголовку X-Verteco-Event. Повний список подій: invoice.received, invoice.sent, invoice.delivered, invoice.rejected, invoice.undeliverable, invoice.reported, company.activated, company.deactivated, company.smp_registered_elsewhere і тестова подія webhook.test. Рекомендуємо відкладати невідомий тип події та логувати його; про новий тип ми завжди повідомляємо заздалегідь. Кожна подія також містить occurredAt (час події, ISO-8601 UTC) для впорядкування, а також eventId (те саме значення, що й у заголовку X-Verteco-Delivery-Id): унікальний для кожної події та незмінний при повторній доставці, тому це правильний ключ дедуплікації (peppolMessageId повторюється в invoice.sent, invoice.delivered та invoice.reported). Події invoice.* містять також часи sentAt, deliveredAt, receivedAt і fsReportedAt (ISO-8601 UTC, null, доки факт не настав). invoice.reported надходить, коли податкове повідомлення до Фінансової адміністрації (TDD) щодо документа передано мережі доставки (§ 85o абз. 11), у разі збою C5 навіть із затримкою в кілька днів. Формальні схеми всіх подій наведено в розділі webhooks специфікації OpenAPI.
Перевірка підпису
Якщо компанія має секрет, ми надсилаємо заголовок X-Verteco-Signature у формі sha256=HMAC-SHA256(secret, raw body) (hex у нижньому регістрі). Завжди обчислюйте HMAC над точними байтами тіла:
import crypto from 'node:crypto';
// rawBody = the exact bytes of the request body (not re-serialized JSON)
function verify(rawBody, header, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}Заголовки кожної доставки: X-Verteco-Event (назва події), X-Verteco-Delivery-Id (= eventId у тілі, однаковий при кожному повторі), X-Verteco-Signature (HMAC вище) і паралельно заголовки за стандартом Standard Webhooks: webhook-id (= eventId), webhook-timestamp (unix-секунди цієї спроби) та webhook-signature = v1,base64(HMAC-SHA256(secret, id + "." + timestamp + "." + body)). Ключ = байти Вашого секрету в UTF-8; бібліотека standardwebhooks очікує його як whsec_ + base64(secret). Рекомендована обробка: перевірте підпис, відхиляйте доставку з webhook-timestamp старшим за 5 хвилин (захист від повторного відтворення), обробляйте ідемпотентно за eventId, відповідайте 2xx протягом 15 секунд, а важку обробку відкладайте у власну чергу. Невдалу доставку ми повторюємо 8 разів з інтервалом від 30 с до 1 год; потім вона потрапляє в dead-letter із сповіщенням e-mail і залишається видимою в Realtime-логу. Продуктивна webhook-URL має бути https://; тестове середовище приймає також http://.
POST /companies/{id}/webhook/secret; він повертається один раз (ротація генерує новий). Без секрету ми не надсилаємо заголовок X-Verteco-Signature.Масове налаштування: один токен, кілька компаній
Один API-токен (прив'язаний до Вашого облікового запису / електронної адреси) керує усіма компаніями, якими він володіє: хто створює компанію через POST /companies, стає її owner і може налаштувати її вебхук. Вебхук є окремим для кожної компанії (власна URL і секрет), тож одним і тим самим токеном Ви можете підключити будь-яку кількість компаній:
# 1) list of your companies (paginated, see Companies)
curl 'https://peppol.verteco.digital/api/v1/companies?page=0&limit=100' -H 'Authorization: Bearer vpt_8f2a…'
# 2) for EACH company {id}: set the webhook (and/or e-mail)
curl -X PUT https://peppol.verteco.digital/api/v1/companies/{id}/notifications \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"webhookUrl":"https://vas-system.sk/peppol/webhook","notificationEmail":"faktury@firma.sk"}'
# 3) fetch the signing secret (returned ONLY ONCE) and store it for signature verification
curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/webhook/secret -H 'Authorization: Bearer vpt_8f2a…'
# → { "secret": "…" }- Токен має бути
owner/adminвідповідної компанії; для компанії, де він лише member/viewer, повертається403 forbidden(жодного доступу між клієнтами (cross-tenant)). - Кожній компанії можна задати іншу URL або одну й ту саму для всіх; у payload Ви розрізняєте їх за
companyId(іreceiverId). - За сотень компаній дотримуйтеся ліміту запитів на токен (поточне значення повертається в заголовку
RateLimit-Limit); групуйте запити з затримкою (backoff) при429(заголовокRetry-After). - Вебхук фактично спрацьовує лише тоді, коли компанія активна в Peppol (після вибору Verteco як постачальника у Фінансовій адміністрації) і, отже, фактично отримує документи.
Моделі даних
Поля об'єктів, які повертає API.
Company
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
id | UUID | – | ідентифікатор компанії |
ico | string | – | реєстраційний номер компанії (IČO, 8 цифр) |
dic | string|null | – | номер платника ПДВ (IČ DPH) |
legalName | string | – | юридична назва |
registeredAddress | string|null | – | адреса зареєстрованого офісу |
peppolParticipantId | string|null | – | учасник Peppol (після реєстрації) |
status | string | – | pending_verification | active |
role | string | – | owner | admin | member | viewer (Ваша роль) |
createdAt | Instant | – | час створення |
Document
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
id | UUID | – | ідентифікатор документа |
direction | string | – | sent | received |
peppolMessageId | string|null | – | ID повідомлення Peppol |
docTypeId | string|null | – | тип документа (Peppol) |
senderId | string|null | – | відправник (scheme:id) |
receiverId | string|null | – | отримувач (scheme:id) |
invoiceNumber | string|null | – | номер рахунка |
issueDate | date|null | – | дата виставлення |
currency | string|null | – | валюта (напр. EUR) |
totalAmount | number|null | – | загальна сума |
status | string | – | стан обробки |
createdAt | Instant | – | час запису |
User · Token · Webhook
| Поле | Тип | Обовʼязкове | Опис |
|---|---|---|---|
User | object | – | { id: UUID, email: string } |
Token | object | – | { id, name, prefix, lastUsedAt|null, createdAt } |
Webhook | object | – | { url: string|null, hasSecret: boolean } |
Словацькі конвенції з практики розробників
Поза межами Peppol BIS Billing 3.0 словацькі постачальники ERP і програм для виставлення рахунків поступово сходяться на спільній інтерпретації опціональних полів (обговорення відбувається в Slack-каналі, який веде Фінансова адміністрація Словаччини, Finančná správa, FS). Нижче наведено конвенції, яких наш портал дотримується вже сьогодні: усі вони є валідними конструкціями BIS, проходять через наше API без змін, а отримані документи відображають їх також у зрозумілому для людини попередньому перегляді та PDF.
- Вирахування оподаткованого авансу в рядку: від'ємний рядок із
cac:DocumentReference, деcbc:IDмістить номер податкового документа на отриманий платіж, аcbc:DocumentTypeCodeдорівнює130(BIS: invoice line object identifier, макс. 1 на рядок). Отриманий рахунок із таким рядком відображається в нашому попередньому перегляді з приміткою „odpočet zálohy – daňový doklad č. …" (вирахування авансу, податковий документ №…). - Податковий документ на отриманий платіж: згідно з FAQ Фінансової адміністрації використовується код
InvoiceTypeCode 388(Tax invoice). Він проходить як наше API, так і валідацію; вирахування неоплаченого (неоподаткованого) авансу виражається черезcbc:PrepaidAmount. - Анулювання рахунка: кредит-нота
381(CreditNote) зcac:BillingReferenceна початковий рахунок, а не від'ємний рахунок 380. Примітка: мережа відхиляє код 384 для словацьких сторін (правило PEPPOL-EN16931-P0112 дозволяє його лише між німецькими суб'єктами); для коригування в бік збільшення використовуйте дебет-ноту 383. - BT-83 PaymentID: словацька практика сходиться на форматі референсу платника
/VS…/SS…/KS…; лише змінний символ (variabilný symbol) також поширений. Наша обробка передає значення без змін і відображає його разом із платіжними реквізитами. - Додаткові дані позицій (партії, серійні номери, терміни придатності) через
cac:AdditionalItemPropertyз усталеними назвами, такими якBatchNumber,SerialNumber,ExpirationDate.
Вкладення документів (BT-125)
Вкладення (PDF, зображення) можна додати до е-рахунка у форматі base64 в елементі cac:AdditionalDocumentReference (BT-125). Наш ліміт: 25 МБ на вкладення. Peppol не визначає єдиного ліміту для всієї мережі; окремі постачальники встановлюють власні (FS FAQ 9/DPH/2025/IM, приклад № 67), тому для дуже великих вкладень також перевірте ліміт постачальника іншої сторони.
Публічні інструменти (валідація, перевірка отримувача)
Два допоміжні endpoint-и без автентифікації: те саме ядро валідації і той самий SML/SMP lookup, які використовує наш Access Point. Вони підходять для CI та перевірок перед відправленням; на них діє суворіший публічний ліміт запитів.
/public/peppol-validateпублічнийВалідація е-рахунка за EN 16931 + Peppol BIS Billing 3.0 (включно зі словацькими правилами), те саме, що й UI-валідатор на /validator. Тіло запиту = безпосередньо UBL 2.1 XML (Invoice / CreditNote або весь Peppol SBD), Content-Type application/xml, ліміт 3 МБ.
curl -X POST https://peppol.verteco.digital/api/v1/public/peppol-validate \
-H "Content-Type: application/xml" \
--data-binary @faktura.xml// 200 OK
{
"valid": false,
"errors": [
"BR-CO-09: [BR-CO-09]-The Seller VAT identifier (BT-31) … shall have a prefix in accordance with ISO code…"
],
"warnings": []
}
// 400 = empty body (empty_document) or document over 3 MB (document_too_large)/public/peppol-check?id=0245:2121358349публічнийПеревірка отримувача в робочій мережі Peppol (SML/SMP lookup): чи він зареєстрований і які типи документів може отримувати? Параметр id приймає Peppol ID (0245:…), номер платника ПДВ (IČ DPH, SK…) або сам DIČ (словацький податковий ідентифікаційний номер). Автентифікований еквівалент для ERP-конвеєрів: GET /sapi/discovery.
// 200 OK
{
"registered": true,
"participantId": "0245:2121358349",
"smp": "sml.peppol-smp.sk",
"capabilities": ["Faktúra (BIS Billing)", "Dobropis", "Self-billing", "MLS doručenky"], // Slovak labels: Invoice (BIS Billing), Credit note, Self-billing, MLS delivery receipts
"lastCheckedAt": "2026-08-31T…Z"
}MCP-сервер (ШІ-асистенти)
Портал має власний сервер для Model Context Protocol, відкритого стандарту, через який ШІ-асистенти (Claude Code, Claude Desktop, Cursor, VS Code Copilot та інші) підключаються до зовнішніх систем. Асистент входить звичайним API-ключем облікового запису й отримує шість інструментів; він ніколи не бачить більше, ніж цей обліковий запис, і кожен виклик з’являється в журналі API ключа.
Адреса: https://peppol.verteco.digital/api/mcp. Транспорт: Streamable HTTP, JSON-RPC 2.0, без стану (POST /api/mcp, без SSE-потоку, GET повертає 405). Вхід заголовком Authorization: Bearer <API-ключ>. Підтримувані методи: initialize, ping, tools/list, tools/call, resources/list, prompts/list.
Інструменти
list_companies: компанії облікового запису з Peppol ID, станом і роллю (початок кожної розмови)list_documents: надіслані/отримані рахунки компанії зі станом доставки та звіту до податкової, посторінковоget_document: один рахунок детально, включно з квитанцією MLS і звітом, за бажанням UBL XML (до 1 МБ)check_participant: жива перевірка отримувача в мережі Peppol (SML/SMP)validate_document: валідація UBL за EN 16931 + BIS 3.0 зі словацькими правиламиsend_document: надсилання рахунка від імені компанії, потребує confirm = true, діє перевірка Verifikačný údaj
Підключення в Claude Code
claude mcp add --transport http verteco-peppol https://peppol.verteco.digital/api/mcp \
--header "Authorization: Bearer vpt_..."Claude Desktop (через міст mcp-remote, потрібен Node.js)
{
"mcpServers": {
"verteco-peppol": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://peppol.verteco.digital/api/mcp", "--header", "Authorization: Bearer vpt_..."]
}
}
}Надсилання рахунка є юридично зобов’язальним: інструмент відхиляє виклик без confirm = true, а інструкції сервера зобов’язують асистента отримати явну згоду користувача на конкретний рахунок і отримувача. Готові конфігурації для Cursor і VS Code та кнопка створення ключа є в порталі: API-ключі → вкладка MCP-сервер. API-ключі → MCP-сервер
Стан (ping)
Публічний endpoint перевірки стану (health-check), придатний для моніторингу.
/pingпублічнийСтан backend.
// 200 OK
{ "service": "peppol-portal-backend", "status": "ok", "timestamp": "2026-06-17T…Z" }Актуальний огляд усіх компонентів доступний на сторінці стану системи.
Незабаром
- POST
/companies/{id}/peppol/register· Ручна реєстрація в Peppol SMP через API. Сьогодні це відбувається автоматично при виборі постачальника на порталі FS (VPDS) Фінансової адміністрації Словаччини (Finančná správa, FS).
POST /companies/{id}/documents/send уже доступний (beta: форма відповіді ще може змінитися); для стабільного програмного відправлення рекомендуємо SAPI-SK POST /sapi/document/send із Idempotency-Key.Хочете отримати ранній доступ до інтеграції, sandbox або маєте запитання? Зв'яжіться з нами безпосередньо:
