Integracijski pristup za KPD 2025 radne provjere

Detaljna REST dokumentacija za interne sustave: autentifikacija, endpointi, struktura zahtjeva i odgovora, status kodovi, pravila ponovnog pokušaja i primjeri integracije za više jezika.

Kako integracijsko sučelje radi u stvarnom radnom tijeku

Vanjski sustav pošalje opis stavke i opcionalni poslovni kontekst. Servis vraća strukturirani JSON s najjačim KPD prijedlogom, povezanim NKD smjerom, signalom sigurnosti, upozorenjima i alternativama. Taj rezultat možete odmah spremiti uz artikl, dokument, cjenik ili interni revizijski trag.

Za vanjsko povezivanje koristi se verzioniranu krajnju točku /api/v1/classify s pristupnim ključem. Krajnja točka /api/status služi za provjeru dostupnosti. Interna provjera kroz istu domenu kroz korisničku sesiju postoji zasebno, ali za međusloj, red čekanja ili sustavsko povezivanje preporuka je uvijek koristiti javno verzionirano tehničko sučelje.

Primarna uporaba

Batch importi, sinkronizacija kataloga, interni middleware servisi i drugi poslovni tokovi.

Minimalan payload

Dovoljno je poslati query. Za višu točnost preporučeno je poslati i type te po potrebi supplement.

Operativni rezultat

Osim koda, dobivate i signal sigurnosti, upozorenja i dodatna pitanja za rubne i miješane slučajeve.

Osnovne rute

Endpointi

POST https://kpdinfo.hr.icode.com.hr/api/v1/classifyPOST https://kpdinfo.hr.icode.com.hr/api/v1/batchGET https://kpdinfo.hr.icode.com.hr/api/statusGET https://kpdinfo.hr.icode.com.hr/api/admin/classifier-healthGET https://kpdinfo.hr.icode.com.hr/api/admin/manual-exact-queries

Autorizacija

Authorization: Bearer <API_KEY> je preporučeni način. Podržan je i X-API-Key.

Format

Request i response su JSON. Za stabilan rad pošaljite i Accept: application/json.

Timeout

Praktična preporuka za klijentski vremenski limit je 15–20 sekundi, uz ponovni pokušaj samo za odgovore 429 i 5xx.

Request schema

Polja zahtjeva

PoljeTipObaveznoOpis
querystringDaOpis stvarne stavke, usluge, robe ili procesa koji želite klasificirati.
typestringNeKontekst isporuke, npr. Usluge, Prodaja na veliko, Prodaja na malo, Proizvodnja.
contextstringNeAlternativni naziv za isto polje; servis prihvaća type ili context.
supplementstringNeDodatna nadopuna opisa kad osnovni naziv nije dovoljno precizan.
metaobjectNeVaš interni identifikator artikla, dokumenta, reda cjenika ili izvora podataka.

Najveću razliku u točnosti obično ne radi sam naziv proizvoda, nego točan opis poslovnog modela: prodaja, usluga, ugradnja, održavanje, najam, otkup, obrada ili proizvodnja.

Payload primjer

Preporučeni zahtjev

{ "query": "Odvoz starog željeza iz poslovnog prostora", "type": "Usluge", "supplement": "bez obrade i bez otkupa", "meta": { "itemId": "erp-4582", "source": "ulazni-cjenik-2026" } }

Kad koristiti supplement

Kad osnovni naziv ne razlikuje dovoljno jasno prodaju, uslugu, ugradnju, obradu, otkup ili reciklažu.

Kad koristiti type

Kad vaš sustav već zna je li riječ o robi, usluzi, proizvodnji ili prodajnom kanalu.

Response schema

Odgovor integracijskog sučelja

Javni verzioniranu krajnju točku /api/v1/classify vraća sažeti, stabilni response format namijenjen integracijama. Ključna polja su ispod.

{ "ok": true, "kpdCode": "38.11.19", "kpdName": "Usluge skupljanja neopasnog oporabljivog otpada, d. n.", "nkdCode": "38.11", "nkdName": "Skupljanje neopasnog otpada", "confidence": 89, "status": "Visoka sigurnost", "reasoning": "BrenAI je prepoznao uslugu skupljanja i odvoza neopasnog metalnog otpada bez signala da je fokus na trgovini ili oporabi.", "alternatives": [ { "kpdCode": "46.87.00", "kpdName": "Trgovina na veliko ostacima i otpacima", "reason": "Ako je fokus na otkupu ili trgovini." } ], "warnings": [], "followUpQuestions": [], "guidance": null, "detectedIndustry": null }
HTTP ponašanje

Statusni kodovi i pravila ponovnog pokušaja

200 Zahtjev je uspješno obrađen i vraćen je klasifikacijski rezultat.
400 Payload nije valjan, nedostaje query ili su vrijednosti u krivom formatu.
401 Pristupni ključ nedostaje, nije valjan ili je opozvan.
403 Ključ postoji, ali nema pravo pristupa resursu ili domena nije dopuštena.
405 Ruta postoji, ali metoda nije podržana.
429 Dosegnut je limit zahtjeva; poštujte Retry-After header.
500 Privremena interna greška; uvedite retry s backoff logikom.

429 rate limit

Poštujte Retry-After header i uvedite kontrolirani retry. Nemojte odmah slati isti zahtjev u petlji.

5xx odgovori

Preporuka je eksponencijalni backoff, npr. 1 s → 2 s → 4 s, uz ograničen broj pokušaja.

4xx odgovori

To su u pravilu poslovne ili autorizacijske greške i obično ih ne treba slijepo retryati bez promjene payloada ili ključa.

Operativne preporuke za produkciju

Integracijsko sučelje je dovoljno jednostavno za izravne pozive, ali u ozbiljnijem povezivanju vrijedi nekoliko pravila koja pomažu da rezultat ostane provjerljiv i upotrebljiv i kada opis nije savršen.

Spremite izvorni unos

Uz rezultat zadržite i izvorni query, poslovni kontekst i interni identifikator stavke.

Ne ignorirajte upozorenja

Upozorenja i dodatna pitanja služe upravo za rubne i miješane slučajeve u kojima pogrešna podkategorija može imati poslovne posljedice.

Vodite revizijski trag

Spremite korisničku odluku kad operator ručno potvrdi ili zamijeni šifru. To kasnije pomaže i u internoj validaciji.

Provjera dostupnosti

Statusna krajnja točka

GET https://kpdinfo.hr.icode.com.hr/api/status

Statusna krajnja točka korisna je za deploy proces, nadzor dostupnosti i jednostavne provjere spremnosti prije većeg slanja datoteka.

{ "ok": true, "status": "ok", "version": "13.x", "services": { "api": "ok", "classifier": "ok", "storage": "ok" } }

Primjeri integracije za više programskih jezika

Tehničko sučelje koristi standardni HTTP i JSON, pa ga možete povezati iz gotovo bilo kojeg programskog jezika, frameworka ili pozadinskog procesa koji zna poslati HTTPS zahtjev.

cURL
curl -X POST https://kpdinfo.hr.icode.com.hr/api/v1/classify \ -H "Authorization: Bearer kpdai_xxxxx" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "query": "Odvoz starog željeza iz skladišta", "type": "Usluge", "supplement": "bez otkupa i bez oporabe" }'
JavaScript / fetch
const response = await fetch('https://kpdinfo.hr.icode.com.hr/api/v1/classify', { method: 'POST', headers: { Authorization: 'Bearer ' + process.env.KPD_API_KEY, 'Content-Type': 'application/json', Accept: 'application/json' }, body: JSON.stringify({ query: 'Prodaja i ugradnja alu ograde', type: 'Usluge' }) }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); console.log(data.kpdCode, data.nkdCode, data.confidence);
TypeScript
type ClassifyResponse = { kpdCode: string; kpdName: string; nkdCode: string; nkdName: string; confidence: number; status: string; reasoning: string; warnings: string[]; followUpQuestions: string[]; }; const res = await fetch('https://kpdinfo.hr.icode.com.hr/api/v1/classify', { method: 'POST', headers: { Authorization: `Bearer ${process.env.KPD_API_KEY}`, 'Content-Type': 'application/json', Accept: 'application/json' }, body: JSON.stringify({ query: 'Skladištenje i logistička usluga', type: 'Usluge' }) }); const data = (await res.json()) as ClassifyResponse;
PHP
$payload = json_encode([ 'query' => 'Veterinarski pregled psa', 'type' => 'Usluge', ], JSON_UNESCAPED_UNICODE); $ch = curl_init('https://kpdinfo.hr.icode.com.hr/api/v1/classify'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('KPD_API_KEY'), 'Content-Type: application/json', 'Accept: application/json', ], CURLOPT_POSTFIELDS => $payload, CURLOPT_TIMEOUT => 20, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); $data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
Python
import requests response = requests.post( 'https://kpdinfo.hr.icode.com.hr/api/v1/classify', headers={ 'Authorization': 'Bearer ' + KPD_API_KEY, 'Accept': 'application/json' }, json={ 'query': 'Reciklaža otpadnog aluminija', 'type': 'Usluge' }, timeout=20, ) response.raise_for_status() data = response.json()
C# / .NET
using System.Net.Http.Headers; using System.Text; using System.Text.Json; var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); var payload = JsonSerializer.Serialize(new { query = "Online tečaj engleskog jezika", type = "Usluge" }); var response = await client.PostAsync( "https://kpdinfo.hr.icode.com.hr/api/v1/classify", new StringContent(payload, Encoding.UTF8, "application/json") );
Java
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://kpdinfo.hr.icode.com.hr/api/v1/classify")) .header("Authorization", "Bearer " + apiKey) .header("Content-Type", "application/json") .header("Accept", "application/json") .POST(HttpRequest.BodyPublishers.ofString( "{\"query\":\"SEO optimizacija web stranice\",\"type\":\"Usluge\"}" )) .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString());
Go
payload := []byte(`{"query":"Otkup starog željeza","type":"Prodaja na veliko"}`) req, _ := http.NewRequest("POST", "https://kpdinfo.hr.icode.com.hr/api/v1/classify", bytes.NewBuffer(payload)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") resp, err := http.DefaultClient.Do(req)
Ruby
require 'net/http' require 'json' uri = URI('https://kpdinfo.hr.icode.com.hr/api/v1/classify') req = Net::HTTP::Post.new(uri) req['Authorization'] = "Bearer #{ENV['KPD_API_KEY']}" req['Content-Type'] = 'application/json' req['Accept'] = 'application/json' req.body = { query: 'Upravljanje poslovnom zgradom', type: 'Usluge' }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } data = JSON.parse(res.body)

Idempotentni ponovni pokušaj i operativna pravila

Za produkcijske integracije preporuka je da zahtjev prema klasifikatoru tretirate kao zapisivu poslovnu operaciju: pošaljite čisti opis stavke, spremite izvorni payload, odgovor i odluku operatera, a ponovni pokušaj radite samo kod stvarno privremenih pogrešaka.

Ponovni pokušaj

Ponovite zahtjev samo za 429 i 5xx, uz postupno povećavanje razmaka između pokušaja. Za 400, 401 i 403 problem je u poslanim podacima ili autorizaciji, pa ponavljanje bez izmjene nema smisla.

Idempotentnost

Preporuka je da u vlastitom sustavu spremite hash opisa + konteksta i isti zahtjev ne šaljete više puta ako rezultat već postoji i operator ga je potvrdio.

Revizijski trag

Za rubne slučajeve spremite upozorenja, dodatna pitanja i konačnu ručnu odluku. To je najkorisniji trag kada kasnije čistite katalog ili radite skupne korekcije.

Produkcijske preporuke

Brzi kontrolni popis

1. Čist unos

Ne šaljite količine, cijene, PDV i interne oznake ako nisu važne za stvarnu klasifikaciju.

2. Stabilan vremenski limit

Držite klijentski vremenski limit oko 15–20 sekundi i obavezno zabilježite tijelo odgovora u slučaju pogreške.

3. Ručna korekcija

Omogućite operatoru ručnu korekciju i povratnu informaciju kad opis miješa robu, uslugu, najam, upravljanje ili obradu.

Integracijski pristup je pogodan i za prilagođene modele povezivanja

Ako trebate veći promet, odvojeno testno i produkcijsko okruženje, internu obradu kroz red čekanja ili pomoć oko mapiranja KPD rezultata u vlastiti sustav, javite se s kratkim opisom očekivanog volumena.