Potwierdzenia w Codenica API
Pracę z Potwierdzeniami przez Codenica API zaczynasz od utworzenia klucza w ustawieniach Codenica. Jeżeli klucz nie został jeszcze utworzony, otwórz w nowej karcie Codenica API - wprowadzenie. Znajdziesz tam wspólne zasady tworzenia kluczy, przechowywania sekretów i uwierzytelniania.
Potwierdzenie jest rekordem procesu, w którym konkretny klient ma podjąć decyzję. Integracja może przygotować dane, przypisać klienta, dołączyć dokumenty, zasoby, notatki i pliki, a następnie przekazać decyzję do wykonania przez właściwy kontekst Client.
Techniczna nazwa pojedynczego rekordu to confirmation, a nazwa zbioru endpointów to confirmations. Zwykła edycja zmienia opis rekordu. Wyniku decyzji nie zapisuj bezpośrednio w polu status - do zatwierdzenia lub odrzucenia służy dedykowany endpoint /decision.
W przykładach zastosowano identyfikator PUBLIC-API-CONFIRMATION-20260908-0001. Zastąp go własnym identyfikatorem pochodzącym z systemu integrującego, a wartości w nawiasach klamrowych danymi z własnej bazy.
Potwierdzenia - adres API i wybór instalacji
Wszystkie trasy dotyczące Potwierdzeń zaczynają się od:
{BASE_URL}/api/v1/confirmationsBASE_URL oznacza adres serwera Codenica bez końcówki /api/v1. W wersji Cloud użyj domeny lub subdomeny przypisanej do konkretnej firmy:
export BASE_URL="https://{domena-firmy}"W domyślnej instalacji On-Premise program Codenica Discovery rejestruje lokalnie adres:
export BASE_URL="http://codenica.local:5150"Jeżeli administrator udostępnił instalację pod firmową domeną, przez HTTPS, reverse proxy albo na innym porcie, użyj dokładnego adresu przekazanego dla tej instalacji:
export BASE_URL="https://{rzeczywisty-adres-instalacji}"Adres localhost stosuj tylko wtedy, gdy integracja i API działają na tym samym komputerze. Przykład http://localhost:5050 dotyczy lokalnego środowiska deweloperskiego, a nie standardowego adresu On-Premise. Nie przesyłaj tenantId w body ani w query stringu. Właściwa baza danych jest wybierana na podstawie hosta żądania.
Potwierdzenia - zakresy klucza API
Klucz używany do pracy z Potwierdzeniami powinien mieć tylko zakresy potrzebne przez konkretną integrację. Pełny zestaw zakresów modułu wygląda tak:
confirmations:read
confirmations:write
confirmations:delete
confirmations:schema
confirmations:stats
confirmations:relationships:read
confirmations:relationships:write
confirmations:users:read
confirmations:files:read
confirmations:files:write
confirmations:technical:read
confirmations:technical:write
confirmations:pin:write
confirmations:decision:write
users:readDo odczytu list i rekordów wybierz confirmations:read. Tworzenie i zwykła edycja wymagają confirmations:write, a usuwanie confirmations:delete. Zakresy relacji, plików, statystyk, pól technicznych, przypinania i decyzji dodaj tylko wtedy, gdy integracja będzie wykonywać te operacje.
Jeśli integracja wybiera cele relacji z innych zbiorów, potrzebuje także odpowiednich zakresów odczytu, na przykład assets:read, documents:read, clients:read albo notes:read. Sam zakres klucza nie zastępuje uprawnień użytkownika.
Potwierdzenia - uwierzytelnianie żądań
Każde żądanie Codenica API uwierzytelniaj dwoma nagłówkami:
X-Codenica-Client-Id: {CLIENT_ID}
X-Codenica-Client-Secret: {CLIENT_SECRET}
Accept: application/jsonPrzykład pierwszego żądania:
export PUBLIC_API_CLIENT_ID="cna_example"
export PUBLIC_API_CLIENT_SECRET="cns_example"
curl --request GET --url "$BASE_URL/api/v1/context" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET"Zewnętrzna integracja nie potrzebuje administratorowego Bearer JWT ani ciasteczek z panelu Codenica. Client Secret przechowuj po stronie serwera w magazynie sekretów. Nie umieszczaj go w kodzie przeglądarkowym, repozytorium, adresie URL, historii poleceń ani logach. Poza lokalnym developmentem korzystaj z HTTPS.
W odpowiedziach zapisuj meta.requestId. Identyfikator pomaga odnaleźć żądanie w logach, ale nie zastępuje UUID Potwierdzenia i nie jest sekretem.
Potwierdzenia - sprawdzenie kontekstu połączenia
Przed pierwszym zapisem pobierz kontekst. Sprawdzisz w ten sposób, czy adres prowadzi do właściwej bazy danych, a klucz ma wymagane zakresy i limity:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/context"Weryfikuj między innymi data.apiVersion, data.contractVersion, dane data.tenant, wartość data.caller.authentication równą api_key, rolę i clientId wywołującego, obecność confirmations w data.capabilities.resources, zakresy oraz limity.
{
"data": {
"caller": {
"role": "Administrator",
"authentication": "api_key",
"scopes": [
"confirmations:read",
"confirmations:write",
"confirmations:decision:write"
]
},
"capabilities": {
"supportsETag": true,
"supportsIdempotency": true,
"supportsRelationships": true,
"supportsFiles": true
}
},
"meta": { "requestId": "{REQUEST_ID}" }
}Jeżeli kontekst wskazuje inną firmę albo nie zawiera potrzebnego zakresu, popraw adres lub klucz. Nie próbuj kierować żądania do innej bazy przez przesłanie obcego identyfikatora.
Potwierdzenia - schema i cele relacji
Schema jest źródłem informacji o aktualnych polach, ich typach, zapisywalności i dopuszczalnych celach relacji:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/schema"W odpowiedzi znajdziesz między innymi data.itemType, data.fields i data.relationshipTargets. Dla tego modułu itemType ma stałą wartość confirmation. Dla każdego pola sprawdź readable, writable, required, technical, unique i maxLength.
{
"data": {
"itemType": "confirmation",
"fields": [
{ "name": "customId", "type": "string", "writable": true },
{ "name": "status", "type": "string", "writable": false },
{ "name": "pin", "type": "integer", "writable": false }
],
"relationshipTargets": [
{ "targetDataSet": "assets" },
{ "targetDataSet": "clients", "targetItemType": "client" },
{ "targetDataSet": "documents", "targetItemType": "document" },
{ "targetDataSet": "notes", "targetItemType": "note" }
]
}
}Dla assets schema nie narzuca jednego typu obiektu. Jeżeli konkretny cel ma itemType=computer, w żądaniu relacji użyj computer, a nie automatycznie asset. Nie buduj mapowania wyłącznie na podstawie przykładu - przed uruchomieniem integracji pobierz aktualne schema.
Potwierdzenia - pola biznesowe i pola procesu
Najważniejsze pola, które możesz przekazywać w attributes, to:
customIdlocation, departmenttag, linkinfo, descriptiontype, categorystatus, dateConfirmed, dateDeclined, dateEnd, remark, pinPodstawowe maksymalne długości to między innymi: customId 500, location 300, department 300, tag 2000, link 2000, info 10000, type 300, category 300 i description 10000 znaków. Aktualna odpowiedź schema dla danej bazy ma pierwszeństwo.
Pól status, dateConfirmed, dateDeclined, dateEnd, remark i pin nie zapisuj w zwykłym PATCH. Nie wysyłaj też pól audytowych:
creator
updater
dateCreated
dateUpdated
importId
importSource
dateImportedPotwierdzenia - dostępne endpointy
Najważniejsze trasy modułu confirmations to:
GET /api/v1/confirmations
POST /api/v1/confirmations
GET /api/v1/confirmations/{CONFIRMATION_ID}
PATCH /api/v1/confirmations/{CONFIRMATION_ID}
DELETE /api/v1/confirmations/{CONFIRMATION_ID}
GET /api/v1/confirmations/schema
GET /api/v1/confirmations/stats
GET /api/v1/confirmations/values
POST /api/v1/confirmations:batch
GET /api/v1/confirmations/{CONFIRMATION_ID}/relationships
POST /api/v1/confirmations/{CONFIRMATION_ID}/relationships
POST /api/v1/confirmations/{CONFIRMATION_ID}/relationships:batch
DELETE /api/v1/confirmations/{CONFIRMATION_ID}/relationships/{DATASET}/{TARGET_ID}
GET /api/v1/confirmations/{CONFIRMATION_ID}/user-relationships
GET /api/v1/confirmations/{CONFIRMATION_ID}/files
POST /api/v1/confirmations/{CONFIRMATION_ID}/files
POST /api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}
DELETE /api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}
GET /api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}/content
POST /api/v1/confirmations/{CONFIRMATION_ID}/pin
POST /api/v1/confirmations/{CONFIRMATION_ID}/decisionOdczyty wymagają zakresów read, a poszczególne mutacje dodatkowych zakresów zgodnych z ich przeznaczeniem. Każde żądanie zmieniające dane wymaga Idempotency-Key, a operacja na istniejącym rekordzie dodatkowo aktualnego If-Match.
Potwierdzenia - listowanie i paginacja
Listę Potwierdzeń pobieraj stronami. Możesz podać stały itemType=confirmation, chociaż API i tak używa tego typu dla całego modułu:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations?itemType=confirmation&page=1&pageSize=25"Odpowiedź ma kolekcję data.items oraz informacje o stronie:
{
"data": {
"items": [
{
"id": "{CONFIRMATION_ID}",
"itemType": "confirmation",
"attributes": {
"customId": "ERP-CONFIRMATION-2026-0042",
"category": "Zakupy",
"status": "Pending"
},
"meta": { "etag": "{ETAG}" }
}
],
"page": 1,
"pageSize": 25,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false
},
"meta": { "requestId": "{REQUEST_ID}" }
}Przechodź do następnej strony na podstawie hasNextPage. Maksymalny rozmiar strony odczytaj z data.capabilities.limits.maxPageSize, zamiast zakładać go na stałe.
Potwierdzenia - wyszukiwanie i filtry
Parametr search służy do szukania tekstu w polach opisowych. Do synchronizacji najlepiej stosować stabilny customId albo UUID:
curl --silent --show-error -G \
--data-urlencode "search=zakup" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=20" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations"Filtry pól możesz łączyć w jednym żądaniu:
curl --silent --show-error -G \
--data-urlencode "status=Pending" \
--data-urlencode "category=Zakupy" \
--data-urlencode "customId=ERP-CONFIRMATION-2026-0042" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations"Dla bardziej precyzyjnego wyszukiwania użyj filtra strukturalnego w postaci field:operator:value:
category:eq:Zakupy
status:ne:Declined
description:contains:komputer
customId:startswith:ERP-CONFIRMATION-
link:notempty:Przydatne operatory to między innymi eq, ne, contains, startswith, endswith i notempty. Wartości zawierające spacje, dwukropki lub znaki specjalne koduj w adresie URL.
Potwierdzenia - wybór pól i dołączanie danych
Parametr fields ogranicza atrybuty zwracane w odpowiedzi. Przy synchronizacji listy możesz pobierać tylko potrzebne pola:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations?fields=id,customId,status,category&page=1&pageSize=20"Jeżeli potrzebujesz od razu plików, relacji i użytkownika tworzącego rekord, użyj include:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}?fields=%2A&include=files%2Crelationships%2Cusers"Dołączenie plików wymaga confirmations:files:read, relacji confirmations:relationships:read, a użytkowników confirmations:users:read. Ograniczaj fields i include, jeżeli integracja nie potrzebuje pełnego rekordu.
Potwierdzenia - statystyki i wartości pól
Endpoint stats pomaga zbudować podsumowanie widocznych Potwierdzeń, a values dostarcza wartości do list filtrów:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/stats?field=category&limit=20"curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/values?field=category&search=zak&limit=20"Oba endpointy są odczytowe i wymagają confirmations:stats. Wyniki obejmują tylko rekordy widoczne dla użytkownika przypisanego do klucza i nie wymagają ETag-u. Limit parametru limit sprawdź w aktualnym kontrakcie API.
Potwierdzenia - utworzenie rekordu i przypisanie klienta
Potwierdzenie przeznaczone do decyzji powinno wskazywać biznesowego Clienta. To obiekt klienta z bazy danych, a nie identyfikator technicznego AppUsera używanego do logowania:
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}Minimalny payload zawiera stały itemType, opisowe attributes i relację do Clienta:
{
"itemType": "confirmation",
"attributes": {
"customId": "ERP-CONFIRMATION-2026-0042",
"category": "Zakupy",
"description": "Potwierdzenie zakupu stacji roboczej."
},
"relationships": [
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}
]
}Przypisanie można przekazać już podczas tworzenia. Nie dodawaj do tej relacji pola relationshipType.
Potwierdzenia - kompletny przykład utworzenia
W większej integracji warto zapisać body do pliku, aby móc bezpiecznie powtórzyć identyczne żądanie po chwilowym błędzie połączenia:
{
"itemType": "confirmation",
"attributes": {
"customId": "PUBLIC-API-CONFIRMATION-20260908-0001",
"location": "Warszawa",
"department": "IT",
"tag": "integracja,zakupy,akceptacja",
"link": "https://erp.example.com/requests/0001",
"info": "Wniosek przekazany z systemu zakupowego.",
"type": "Zakup sprzętu",
"category": "Zakupy",
"description": "Potwierdzenie zakupu nowej stacji roboczej dla działu IT."
},
"relationships": [
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Idempotency-Key: erp-confirmation-create-0001" \
--data-binary @confirmation-create.json \
"$BASE_URL/api/v1/confirmations"Sukces tworzenia to 201 Created. Odpowiedź zawiera UUID, itemType, atrybuty, metadane z datami, ETag i requestId. Zapisz UUID i ETag, ponieważ będą potrzebne w następnych krokach.
Potwierdzenia - Idempotency-Key i bezpieczne ponowienie
Każde żądanie zmieniające dane przez klucz API musi mieć własny Idempotency-Key. Jeżeli połączenie przerwie się po wysłaniu żądania, ponów dokładnie ten sam request z tym samym kluczem:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: erp-confirmation-create-0001" \
--data-binary @confirmation-create.json \
"$BASE_URL/api/v1/confirmations"Powtórzenie identycznego żądania z tym samym kluczem nie powinno utworzyć drugiego Potwierdzenia. Nie używaj jednego klucza do różnych body ani do różnych operacji. Klucz idempotencji opisuje jedną operację biznesową.
Utworzenie: Idempotency-Key = erp-confirmation-create-0001
Ponowienie: Idempotency-Key = erp-confirmation-create-0001
Nowa edycja: Idempotency-Key = erp-confirmation-update-0001Dla PATCH, pinowania, decyzji, relacji, plików i usuwania używaj osobnych kluczy. Przy kolejnych zmianach zawsze zapisuj ETag zwrócony przez ostatnią udaną operację.
Potwierdzenia - odczyt pojedynczego rekordu
Po utworzeniu lub otrzymaniu UUID możesz pobrać pełne Potwierdzenie:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}?fields=%2A"W odpowiedzi zachowaj ETag z nagłówka HTTP ETag albo z data.meta.etag. Do diagnostyki zachowaj także meta.requestId.
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}?fields=%2A&include=files%2Crelationships%2Cusers"Wersja z include pozwala w jednym odczycie zobaczyć przypisanego Clienta, relacje obiektowe, requestera i pliki. Jeżeli pobierasz tylko dane do synchronizacji, ogranicz odpowiedź parametrem fields.
Potwierdzenia - edycja z aktualnym ETagiem
Bezpieczna edycja wygląda zawsze tak: pobierz rekord, odczytaj aktualny ETag, przygotuj mały PATCH, wyślij If-Match i nowy Idempotency-Key, a następnie zapisz nowy ETag:
{
"attributes": {
"info": "Dane uzupełnione po weryfikacji w systemie zakupowym.",
"category": "Zakupy IT",
"description": "Potwierdzenie zaktualizowane przez integrację."
}
}curl --fail-with-body --silent --show-error \
--request PATCH \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-update-0001" \
--data-binary @confirmation-update.json \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}"Sukces to 200 OK i nowy ETag. W zwykłym PATCH możesz zmieniać pola opisowe, ale nie zapisuj w ten sposób status, dat decyzji, dateEnd, remark ani pin.
Potwierdzenia - ochrona przed równoczesną edycją
Jeżeli nie prześlesz nagłówka If-Match, API odrzuci zmianę:
HTTP 428 Precondition Required
code: if_match_requiredJeżeli prześlesz ETag starszy niż aktualna wersja rekordu, otrzymasz:
HTTP 412 Precondition Failed
code: if_match_failedPo 412 pobierz rekord ponownie, porównaj jego wartości ze zmianą, którą chcesz wykonać, i dopiero wtedy wyślij nowy PATCH. Nie ponawiaj w pętli tego samego żądania ze starym ETagiem.
Nie próbuj omijać kontroli wersji przez wpisywanie pól procesu w body:
{
"attributes": {
"status": "Confirmed",
"dateConfirmed": "2026-09-08T10:30:00Z"
}
}Decyzję wykonuje dedykowany endpoint /decision. Dzięki temu system może sprawdzić właściwego Clienta, aktualny stan procesu i współbieżność.
Potwierdzenia - przypinanie i odpinanie
Przypięcie jest osobną operacją i nie należy do zwykłego PATCH. Dozwolone wartości to null albo liczba od 0 do 3:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-pin-0001" \
--data '{"pin":3}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/pin"Aby odpiąć rekord, wyślij null:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {PINNED_ETAG}" \
--header "Idempotency-Key: erp-confirmation-unpin-0001" \
--data '{"pin":null}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/pin"Obie operacje wymagają confirmations:pin:write. Po każdym działaniu odczytaj nowy ETag oraz sprawdź wartość pola pin.
Potwierdzenia - decyzja klienta
Decyzja jest czynnością biznesową, a nie zwykłą edycją rekordu. Przed jej wykonaniem Potwierdzenie musi być przypisane do Clienta, a żądanie musi pochodzić z klucza reprezentującego tego właściwego Clienta i mieć zakres confirmations:decision:write. API sprawdza także aktualny ETag.
Zatwierdzenie wykonaj przez payload:
{
"confirmed": true,
"remark": "Potwierdzam realizację wniosku."
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_DECISION_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_DECISION_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {DECISION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-decision-0001" \
--data '{"confirmed":true,"remark":"Potwierdzam realizację wniosku."}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/decision"Odrzucenie używa tej samej trasy i wartości false:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_DECISION_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_DECISION_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {DECISION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-decision-0002" \
--data '{"confirmed":false,"remark":"Odrzucam realizację wniosku."}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/decision"Po pozytywnej decyzji status przyjmuje wartość Confirmed, a system zapisuje dateConfirmed, dateEnd i komentarz. Po decyzji negatywnej status to Declined, a system zapisuje dateDeclined, dateEnd i komentarz. Nie ustawiaj tych pól ręcznie.
Potwierdzenia - Client i requester
Relacja do Clienta wskazuje klienta biznesowego, który ma podjąć decyzję. Nie zastępuje jej techniczny identyfikator AppUsera. Przypisanie odczytasz razem z relacjami obiektowymi albo przez pojedynczy rekord z include=relationships.
API udostępnia również osobną, tylko do odczytu kolekcję użytkowników. Zawiera automatycznego requestera, czyli użytkownika, który utworzył Potwierdzenie:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/user-relationships?relationshipType=requester&page=1&pageSize=20"{
"targetId": "{REQUESTER_USER_ID}",
"targetDataSet": "users",
"relationshipType": "requester",
"displayName": "{REQUESTER_NAME}",
"email": "{REQUESTER_EMAIL}",
"role": "{REQUESTER_ROLE}"
}Requester jest ustalany przez system. Nie ustawiaj tej relacji w attributes i nie próbuj zmieniać jej przez endpoint relacji obiektowych. Odczyt wymaga confirmations:users:read.
Potwierdzenia - dozwolone relacje z obiektami
Aktualny katalog celów relacji Potwierdzeń obejmuje cztery grupy:
assetscomputerclientsclientdocumentsdocument lub typ zwrócony przez celnotesnoteKażdy cel musi istnieć, być widoczny dla użytkownika przypisanego do klucza i zgadzać się z listą relationshipTargets zwróconą przez schema. Potwierdzenia nie mają w tym katalogu relacji z dowolnymi innymi zbiorami.
Potwierdzenia - format relacji zwykłej i przypisania Clienta
Relacja do zasobu, dokumentu albo notatki ma pole relationshipType. Przykład relacji do dokumentu:
{
"targetId": "{DOCUMENT_ID}",
"targetDataSet": "documents",
"targetItemType": "invoice",
"relationshipType": "related"
}Przypisanie Clienta jest wyjątkiem. Ma targetDataSet=clients i targetItemType=client, ale nie ma relationshipType:
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}W przypadku zasobów odczytaj rzeczywisty typ obiektu, a następnie prześlij go dokładnie w targetItemType:
assets - targetItemType: computer
documents - targetItemType: invoice
notes - targetItemType: notePowyższe wartości są przykładami. Właściwy typ może być inny w Twojej bazie.
Potwierdzenia - dodawanie, odczyt i usuwanie relacji
Dodanie pojedynczej relacji odbywa się przez POST z obiektem relacji bez dodatkowego opakowania:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-relation-add-0001" \
--data '{"targetId":"{DOCUMENT_ID}","targetDataSet":"documents","targetItemType":"invoice","relationshipType":"related"}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships"Relacje odczytasz jako kolekcję:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships?targetDataSet=documents&relationshipType=related&page=1&pageSize=50"Usunięcie relacji wymaga aktualnego ETag-u Potwierdzenia. W ścieżce podaj zbiór i UUID celu, a typ relacji przekaż w query:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-relation-delete-0001" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships/documents/{DOCUMENT_ID}?relationshipType=related"Dodanie i usunięcie zwraca nową wersję rekordu albo data=true. Po każdej udanej zmianie pobierz nowy ETag.
Potwierdzenia - grupowa zmiana relacji
Jeśli chcesz dodać lub usunąć kilka relacji jednocześnie, użyj relationships:batch. W jednym body możesz przekazać tablice add i remove:
{
"add": [
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
}
],
"remove": [
{
"targetId": "{NOTE_ID}",
"targetDataSet": "notes",
"targetItemType": "note",
"relationshipType": "related"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-relationships-batch-0001" \
--data-binary @confirmation-relationships-batch.json \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships:batch"Odpowiedź zawiera liczniki added, removed i skipped. Batch relacji ma limit odczytywany z kontekstu, wymaga aktualnego ETag-u i zmienia wersję Potwierdzenia. Dla przypisania Clienta zastosuj format bez relationshipType.
Potwierdzenia - lista i upload plików
Najpierw możesz pobrać listę plików przypisanych do Potwierdzenia:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files?page=1&pageSize=50"Element listy zawiera między innymi id, fileName, contentType, size, relationshipType, isMain i downloadUrl. Nowy plik dodaj jako multipart/form-data:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-file-upload-0001" \
--form "[email protected];type=application/pdf" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files?relationshipType=decision-form"{
"data": {
"id": "{FILE_ID}",
"fileName": "formularz-decyzji.pdf",
"contentType": "application/pdf",
"size": 48231,
"relationshipType": "decision-form",
"isMain": false,
"downloadUrl": "/api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}/content"
}
}Upload wymaga confirmations:files:write, aktualnego ETag-u i nowego klucza idempotencji. Limit rozmiaru odczytaj z data.capabilities.limits.maxUploadBytes. Dla Potwierdzeń API nie udostępnia operacji wyboru pliku głównego - nie buduj integracji oczekującej endpointu /main.
Potwierdzenia - pobieranie, podpinanie i usuwanie plików
Treść pliku pobierz przez endpoint content i zapisz w trybie binarnym:
curl --fail-with-body --silent --show-error \
--output formularz-decyzji-pobrany.pdf \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}/content"Jeżeli plik jest już zapisany w systemie, możesz podpiąć go do drugiego Potwierdzenia bez ponownego przesyłania treści:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {SECOND_CONFIRMATION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-file-attach-0001" \
"$BASE_URL/api/v1/confirmations/{SECOND_CONFIRMATION_ID}/files/{FILE_ID}?relationshipType=reference"Odłączenie pliku od konkretnego Potwierdzenia i usunięcie jego ostatniej relacji korzystają z tej samej trasy DELETE:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CONFIRMATION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-file-delete-0001" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}"Attach tworzy relację do istniejącego pliku. Jeżeli plik jest nadal przypisany do źródłowego Potwierdzenia, odłączenie go od drugiego rekordu nie może usuwać źródłowej relacji. Przed usunięciem ostatniej relacji sprawdź listę plików i upewnij się, że usuwasz właściwy element.
Potwierdzenia - operacje batch
Endpoint /api/v1/confirmations:batch pozwala połączyć tworzenie, edycję i usuwanie rekordów. Format używa tablicy items oraz osobnych obiektów create i update:
{
"items": [
{
"operation": "create",
"create": {
"itemType": "confirmation",
"attributes": {
"customId": "ERP-BATCH-CONFIRMATION-A",
"category": "Dostępy",
"description": "Pierwsze Potwierdzenie utworzone zbiorczo."
},
"relationships": [
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}
]
}
},
{
"operation": "update",
"id": "{EXISTING_ID}",
"ifMatch": "{EXISTING_ETAG}",
"update": {
"attributes": {
"description": "Opis zaktualizowany w operacji batch."
}
}
},
{
"operation": "delete",
"id": "{RECORD_TO_DELETE_ID}",
"ifMatch": "{RECORD_TO_DELETE_ETAG}"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: erp-confirmations-batch-0001" \
--data-binary @confirmations-batch.json \
"$BASE_URL/api/v1/confirmations:batch"{
"data": {
"items": [
{
"index": 0,
"operation": "create",
"status": 201,
"id": "{CREATED_ID}",
"data": { "meta": { "etag": "{CREATED_ETAG}" } }
}
],
"succeeded": 1,
"failed": 0
}
}Każda pozycja aktualizacji i usunięcia potrzebuje własnego aktualnego ifMatch. Batch nie jest transakcją all-or-nothing. Przy częściowym wyniku API może zwrócić 207 Multi-Status, dlatego analizuj każdą pozycję osobno i nie ponawiaj operacji, które już zakończyły się sukcesem.
Potwierdzenia - usunięcie rekordu
Przed usunięciem pobierz rekord ponownie, sprawdź UUID i aktualny ETag, a następnie wyślij żądanie z osobnym kluczem idempotencji:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-delete-0001" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}"Poprawna odpowiedź zwraca 200 OK oraz data=true. Po usunięciu sprawdź, czy UUID nie jest już dostępny:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}"Oczekiwany wynik to 404 Not Found z kodem confirmation_not_found. Usunięcie Potwierdzenia nie oznacza automatycznego usunięcia powiązanych dokumentów, zasobów ani notatek.
Potwierdzenia - błędy, limity i bezpieczna kolejność pracy
Błędy mają format Problem Details. W logach zapisuj status, code i requestId, ale nigdy Client Secret ani pełne nagłówki:
validation_failedauthentication_required lub authentication_failedconfirmation_client_requiredconfirmation_not_foundconfirmation_unique_constraint lub confirmation_concurrency_conflictif_match_failed, if_match_requiredconfirmation_decision_rejected, confirmation_pin_rejectedrate_limit_exceededRetry-After.Odczytuj X-RateLimit-Limit i X-RateLimit-Remaining. Cache'uj schema i wartości pól, ogranicz równoległość, a przy 429 stosuj backoff.
Bezpieczna kolejność pracy to: context, schema, wybór Clienta, lista lub odczyt, utworzenie z Idempotency-Key, zapisanie UUID i ETagu, relacje lub pliki, edycja z If-Match, pinowanie, decyzja przez /decision, odczyt weryfikacyjny i dopiero na końcu usunięcie. Ten sam układ możesz odwzorować w n8n, przekazując UUID, ETag i klucze idempotencji między kolejnymi krokami.
