API dokumentacija za KPD 2025 klasifikaciju i integraciju

Detaljna REST dokumentacija za ERP, kataloge, webshopove i interne sustave: autentifikacija, endpointi, request i response schema, status kodovi, retry pravila i primjeri integracije za više jezika.

Kako API radi u stvarnom workflowu

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

Za vanjske integracije koristite verzionirani endpoint /api/v1/classify s API ključem. Endpoint /api/status služi za health check. Interna same-origin klasifikacija kroz korisničku sesiju postoji zasebno, ali za ERP, webshop, middleware ili queue rad preporuka je uvijek ići na javni verzionirani API.

Primarna uporaba

ERP, webshop, POS, batch importi, sinkronizacija kataloga i interni middleware servisi.

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, warnings i follow-up pitanja za rubne i miješane slučajeve.

Osnovne rute

Endpointi

POST https://kpdinfo.hr/api/v1/classifyPOST https://kpdinfo.hr/api/v1/batchGET https://kpdinfo.hr/api/statusGET https://kpdinfo.hr/api/admin/classifier-healthGET https://kpdinfo.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 timeout je 15–20 sekundi uz retry samo za 429 i 5xx odgovore.

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

Vanjski API odgovor

Javni verzionirani endpoint /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

Status kodovi i retry pravila

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 API 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

API je dovoljno jednostavan za izravne pozive, ali u ozbiljnijoj integraciji vrijedi nekoliko pravila koja pomažu da rezultat ostane auditabilan i upotrebljiv i kad opis nije savršen.

Spremite originalni input

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

Ne ignorirajte warnings

Warnings i follow-up pitanja služe upravo za rubne i miješane slučajeve gdje jedna kriva podkategorija može biti skupa.

Radite audit trail

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

Health check

Status endpoint

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

Health endpoint je koristan za deploy pipeline, nadzor dostupnosti i jednostavne readiness provjere prije većeg batch slanja.

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

Primjeri integracije za više programskih jezika

API koristi standardni HTTP + JSON pa ga možete integrirati iz praktično bilo kojeg jezika, frameworka ili job workera koji zna poslati HTTPS zahtjev.

cURL
curl -X POST https://kpdinfo.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/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/api/v1/classify', { method: 'POST', headers: { Authorization: `Bearer ${process.env.KPD_API_KEY}`, 'Content-Type': 'application/json', Accept: 'application/json' }, body: JSON.stringify({ query: 'Fulfillment skladištenje za webshop', 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/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/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/api/v1/classify", new StringContent(payload, Encoding.UTF8, "application/json") );
Java
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://kpdinfo.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/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/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 retry i operativna pravila

Za produkcijske integracije preporuka je da zahtjev prema klasifikatoru tretirate kao zapisivu poslovnu operaciju: pošaljite čisti opis stavke, spremite originalni payload, odgovor i odluku operatera te retry radite samo za stvarno privremene greške.

Retry

Ponovite zahtjev samo za 429 i 5xx uz exponential backoff. Za 400, 401 i 403 problem je u payloadu ili autorizaciji i retry bez izmjene nema smisla.

Idempotency

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.

Audit trail

Za rubne slučajeve spremite i upozorenja, follow-up pitanja i konačnu ručnu odluku. To je najkorisniji trag kad kasnije čistite katalog ili radite batch korekcije.

Produkcijske preporuke

Brzi checklist

1. Čisti input

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

2. Stabilan timeout

Držite klijentski timeout oko 15–20 sekundi i obavezno logirajte response body za greške.

3. Manual override

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

API je pogodan i za prilagođene integracijske modele

Ako trebate veći promet, više klijenata, zasebni sandbox/prod workflow, internu queue obradu ili pomoć oko mapiranja KPD rezultata u vaš ERP, javite se s kratkim opisom sustava i očekivanog volumena.