VitaHub API v1
Preporuka i pretraga doktora na osnovu dijagnoze, simptoma, procedure ili imena.
diagnosis-doctor
Pretraga po MKB kodu
symptom-doctor
AI analiza simptoma
wanted-doctor
Pretraga konkretnog doktora
procedures-doctor
Pretraga po proceduri
Search / Autocomplete:
Autentifikacija
Svaki zahtev mora sadržati API ključ. Bez validnog ključa API vraća 401.
Obavezan header:
X-API-Key: <vas_api_kljuc>Zajednička pravila
Ova polja važe za sva četiri endpointa:
| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| patientGender | string | Da | muski, musko, m, male, zenski, zensko, z, female |
| patientAge | number | Uslovno | Godine. Obavezno ako nema patientMonths |
| patientMonths | number | Uslovno | Meseci. Obavezno ako nema patientAge |
| desiredLocation | string | Ne | Željeni grad/region |
| preferredLanguages | string[] | Ne | npr. ["srpski", "engleski"] |
Recommendation objekat
Kad bilo koji endpoint vrati doktore, svaki element u data.recommendations[] ima ovaj oblik:
{
"id": 349,
"fullName": "Dr Milos Pasic",
"specialties": [
{ "name": "Interna medicina", "level": "specialty" },
{ "name": "Kardiologija", "level": "subspecialty" },
{ "name": "Interventna kardiologija", "level": "narrowSubspecialty" }
],
"currentInstitutions": [
{
"name": "Dom Zdravlja",
"address": "Bulevar Oslobodjenja 45, Beograd",
"latitude": 44.7866,
"longitude": 20.4489,
"acceptsNewPatients": true
}
],
"languages": ["srpski", "engleski"],
"patientGroups": {
"gender": "zene i muskarci",
"ageGroup": "odrasli"
},
"whyRecommended": ["Iskustvo sa trazenom dijagnozom"],
"recommendationScore": 123,
"canSolveProblem": true
}Nivoi specijalizacije
| Level | Značenje | Primer |
|---|---|---|
| specialty | Specijalnost | Interna medicina |
| subspecialty | Subspecijalnost | Kardiologija |
| narrowSubspecialty | Uža subspecijalizacija | Interventna kardiologija |
Samo nivoi koji postoje za datog doktora se vraćaju. Doktor sa jednom specijalnošću ima niz od jednog objekta.
/v1/search/diagnoses
Autocomplete pretraga MKB-10 dijagnoza. Koristi rezultat kao diagnosisCode u diagnosis-doctor.
Request
GET /v1/search/diagnoses?q=hipert&limit=5| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| q | string | Da | Search term, min 2 karaktera |
| limit | number | Ne | Default: 10, max: 50 |
Response — 200
{
"success": true,
"data": {
"results": [
{
"code": "I10",
"name": "Esencijalna (primarna) hipertenzija",
"category": "Bolesti sistema krvotoka"
},
{
"code": "I11",
"name": "Hipertenzivna bolest srca",
"category": "Bolesti sistema krvotoka"
}
],
"totalFound": 2
}
}/v1/search/procedures
Autocomplete pretraga medicinskih procedura. Svaki rezultat se može direktno proslediti kao element searchItems u procedures-doctor.
Request
GET /v1/search/procedures?q=CT%20grudnog| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| q | string | Da | Search term, min 2 karaktera |
| limit | number | Ne | Default: 10, max: 50 |
Response — 200
{
"success": true,
"data": {
"results": [
{
"id": 101,
"name": "CT grudnog koša",
"level": "diagnostic",
"isExamination": false
},
{
"id": 102,
"name": "CT grudnog koša sa kontrastom",
"level": "diagnostic",
"isExamination": false
}
],
"totalFound": 2
}
}/v1/search/specialties
Autocomplete pretraga specijalnosti na sva tri nivoa. Svaki rezultat se može proslediti kao element specialtyItems u procedures-doctor.
Request
GET /v1/search/specialties?q=kardio| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| q | string | Da | Search term, min 2 karaktera |
| limit | number | Ne | Default: 10, max: 50 |
Response — 200
{
"success": true,
"data": {
"results": [
{
"id": 12,
"name": "Kardiologija",
"level": "subspecialty"
},
{
"id": 45,
"name": "Interventna kardiologija",
"level": "narrowSubspecialty"
}
],
"totalFound": 2
}
}/v1/search/symptoms
Autocomplete pretraga simptoma. Rezultat se može koristiti za poboljšanje korisničkog unosa pre poziva symptom-doctor endpointa.
Request
GET /v1/search/symptoms?q=bol%20u%20grudima| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| q | string | Da | Search term, min 3 karaktera |
| limit | number | Ne | Default: 10, max: 50 |
Response — 200
{
"success": true,
"data": {
"results": [
{
"id": 201,
"name": "Bol u grudima",
"category": "Kardiovaskularni simptomi"
},
{
"id": 202,
"name": "Bol u grudima pri disanju",
"category": "Respiratorni simptomi"
}
],
"totalFound": 2
}
}Minimalna dužina upita je 3 karaktera (za razliku od ostalih search endpointa koji zahtevaju 2).
/v1/search/doctors
Autocomplete pretraga doktora po imenu/prezimenu. Opciono filtriranje po specijalnosti. Rezultat se može koristiti za popunjavanje preferredDoctor u wanted-doctor.
Request
GET /v1/search/doctors?q=Marko&id=12&level=specijalnost| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| q | string | Da | Ime ili prezime doktora, min 2 karaktera |
| id | number | Uslovno | ID specijalnosti — obavezan ako je level prosleđen |
| level | string | Uslovno | "specijalnost" | "subspecijalnost" — obavezan ako je id prosleđen |
| limit | number | Ne | Default: 10, max: 50 |
Parametri id i level su par — ako se prosledi jedan, mora i drugi. Inače API vraća 400.
Response — 200
{
"success": true,
"data": {
"results": [
{
"id": 349,
"fullName": "Dr Marko Marković",
"specialties": [
{ "name": "Neurologija", "level": "subspecialty" }
],
"currentInstitutions": [
{
"name": "KBC Zemun",
"address": "Vukova 9, Beograd"
}
]
},
{
"id": 512,
"fullName": "Dr Marko Nikolić",
"specialties": [
{ "name": "Interna medicina", "level": "specialty" },
{ "name": "Kardiologija", "level": "subspecialty" }
],
"currentInstitutions": [
{
"name": "BelMedic",
"address": "Koste Jovanovića 87, Beograd"
}
]
}
],
"totalFound": 2
}
}Response — 200 (sa specijalnost filterom)
GET /v1/search/doctors?q=Marko&id=12&level=subspecijalnostVraća samo doktore čije ime sadrži "Marko" i koji imaju subspecijalnost sa ID-jem 12.
/v1/diagnosis-doctor
Preporuka doktora na osnovu MKB dijagnoze.
Request
{
"patientAge": 35,
"patientGender": "musko",
"diagnosisCode": "I10",
"desiredLocation": "Beograd",
"preferredLanguages": ["srpski", "engleski"],
"page": 1,
"limit": 10
}| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| diagnosisCode | string | Da | MKB-10 kod (npr. I10) |
| page | number | Ne | Default: 1 |
| limit | number | Ne | Default: 10 |
+ sva zajednička polja
Response — 200
{
"success": true,
"data": {
"recommendations": [ /* Recommendation objekti */ ],
"totalFound": 5,
"searchSummary": {
"diagnosisName": "Povisen krvni pritisak",
"patientProfile": "Odrastao, muskarci, 35 god.",
"searchCriteria": ["Dijagnoza: I10", "Lokacija: Beograd"]
},
"page": 1,
"hasMore": false
},
"metadata": {
"timestamp": "2026-03-31T10:00:00.000Z",
"processingTimeMs": 556
}
}/v1/symptom-doctor
AI analiza simptoma sa dvostepenim tokom.
Može vratiti NEEDS_MORE_INFO (AI traži dodatna pitanja) ili DOCTORS_FOUND (konačna preporuka).
Request — prvi poziv
{
"patientAge": 45,
"patientGender": "zenski",
"symptoms": "Imam jak bol u grudima koji se siri u levu ruku.",
"desiredLocation": "Novi Sad",
"preferredLanguages": ["engleski"]
}| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| symptoms | string | Da | Slobodan opis simptoma |
Request — follow-up (sa odgovorima)
{
"patientAge": 45,
"patientGender": "zenski",
"symptoms": "Imam jak bol u grudima koji se siri u levu ruku.",
"additionalQuestions": [
{
"question": "Da li se bol pojacava pri disanju?",
"answer": "Da"
}
]
}Response — NEEDS_MORE_INFO
{
"success": true,
"status": "NEEDS_MORE_INFO",
"message": "Additional information is required for a more precise diagnosis.",
"data": {
"additionalQuestionAI": [
"Kada je bol poceo?",
"Da li imate gusenje?"
],
"reason": "Potrebno je vise podataka za precizniju preporuku."
}
}Response — DOCTORS_FOUND
{
"success": true,
"status": "DOCTORS_FOUND",
"data": {
"recommendations": [ /* Recommendation objekti */ ],
"totalFound": 3,
"searchSummary": {
"diagnosisName": "Akutni koronarni sindrom",
"patientProfile": "odrasli, zene",
"searchCriteria": ["Interventna kardiologija"]
}
},
"aiMetadata": {
"isUrgent": true,
"summary": "Preporucuje se hitan pregled kod interventnog kardiologa.",
"recommendations": [
{
"type": "subSpecialty",
"name": "Interventna kardiologija",
"recommendedLevel": "subspecialty",
"id": 123,
"reason": "Simptomi ukazuju na akutni koronarni sindrom."
}
]
}
}/v1/wanted-doctor
Pretraga konkretnog doktora + fallback preporuke ako nije dobar match.
Request
{
"patientAge": 32,
"patientGender": "musko",
"symptoms": "Vrtoglavica i trnjenje leve ruke vec 2 dana",
"desiredLocation": "Beograd",
"preferredLanguages": ["srpski"],
"preferredDoctor": {
"firstName": "Marko",
"lastName": "Markovic",
"specialization": "neurolog"
}
}| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| symptoms | string | Da | Min 10 karaktera |
| preferredDoctor | object | Ne | firstName, lastName, opciono specialization |
Mogući statusi
| Status | Opis |
|---|---|
| NEEDS_MORE_INFO | Potrebna su dodatna pitanja |
| WANTED_DOCTOR_MATCH | Tačan match, doktor može da pomogne |
| MORE_THAN_ONE_WANTED_DOCTOR_MATCH | Više doktora odgovara imenu |
| WANTED_DOCTOR_MISMATCH | Doktor pronađen ali nije odgovarajuć za problem |
| DOCTOR_NOT_FOUND | Doktor nije u VitaHub sistemu |
Response — WANTED_DOCTOR_MATCH
{
"success": true,
"status": "WANTED_DOCTOR_MATCH",
"message": "Zeljeni doktor je pronadjen i moze da vam pomogne",
"data": {
"recommendations": [ /* Recommendation objekti */ ],
"totalFound": 1
}
}Response — DOCTOR_NOT_FOUND
{
"success": true,
"status": "DOCTOR_NOT_FOUND",
"message": "Trenutno doktor kog ste trazili nije deo VitaHub sistema."
}/v1/procedures-doctor
Pretraga doktora po medicinskoj proceduri. Podržava slobodan tekst ili strukturirane stavke.
Request — slobodan tekst
{
"patientAge": 40,
"patientGender": "musko",
"desiredLocation": "Beograd",
"preferredLanguages": ["srpski"],
"procedure": "Kardioloski pregled",
"page": 1,
"limit": 10
}Request — strukturirane stavke
{
"patientAge": 40,
"patientGender": "musko",
"searchItems": [
{
"id": 101,
"name": "CT grudnog kosa",
"level": "diagnostic",
"isExamination": false
}
],
"specialtyItems": [
{
"id": 12,
"name": "Radiologija",
"level": "specialty"
}
]
}| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| procedure | string | Uslovno | Obavezno ako nema searchItems |
| searchItems | array | Uslovno | Obavezno ako nema procedure |
| specialtyItems | array | Ne | Opcioni filter po specijalnosti |
| page | number | Ne | Default: 1 |
| limit | number | Ne | Default: 10 |
searchItems objekat:
| Polje | Tip | Obavezno | Napomena |
|---|---|---|---|
| id | number | Da | ID procedure |
| name | string | Da | Naziv procedure |
| level | string | Da | npr. "diagnostic" |
| isExamination | boolean | Da | Da li je pregled |
Response — 200
{
"success": true,
"data": {
"recommendations": [ /* Recommendation objekti */ ],
"totalFound": 12,
"searchSummary": {
"procedureName": "CT grudnog kosa",
"patientProfile": "Odrastao, muskarci, 40 god.",
"searchCriteria": ["Lokacija: Beograd", "Jezici: srpski"]
},
"page": 1,
"hasMore": true
},
"metadata": {
"timestamp": "2026-03-31T10:00:00.000Z",
"processingTimeMs": 420
}
}Error handling
Svi errori prate istu strukturu:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Opis greske."
},
"metadata": {
"timestamp": "2026-03-31T10:00:00.000Z",
"requestId": "uuid"
}
}Error kodovi
| HTTP | Code | Kad se dešava |
|---|---|---|
| 400 | VALIDATION_ERROR | Nedostaju ili nevalidna polja |
| 400 | MISSING_AGE | Ni patientAge ni patientMonths nisu prosleđeni |
| 400 | MISSING_SEARCH_INPUT | procedures-doctor: ni procedure ni searchItems |
| 401 | UNAUTHORIZED | Nema API ključa u headeru |
| 401 | INVALID_API_KEY | API ključ nije prepoznat ili je istekao |
| 403 | FORBIDDEN | Validan ključ ali nema pristup endpointu |
| 404 | ENDPOINT_NOT_FOUND | Pogrešan URL |
| 429 | RATE_LIMIT_EXCEEDED | Previše zahteva — poštovati Retry-After header |
| 500 | INTERNAL_ERROR | Neočekivana greška na serveru |
| 502 | AI_SERVICE_ERROR | AI provider (analiza simptoma) privremeno nedostupan |
| 503 | SERVICE_UNAVAILABLE | Server na održavanju ili preopterećen |
Validation error detalji
400 greške uključuju specifična polja:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed.",
"details": [
{
"field": "diagnosisCode",
"message": "Diagnosis code is required."
},
{
"field": "patientGender",
"message": "Must be one of: muski, musko, m, male, zenski, zensko, z, female."
}
]
}
}401 vs 403
401 — nema ključa, ili ključ ne postoji u sistemu.
403 — ključ je validan ali nema dozvolu za ovaj endpoint.
AI Service Error (symptom-doctor)
Ako je AI backend privremeno nedostupan:
{
"success": false,
"error": {
"code": "AI_SERVICE_ERROR",
"message": "Symptom analysis service is temporarily unavailable. Please retry."
}
}Ostali endpointi koji ne zavise od AI-ja (diagnosis-doctor, procedures-doctor) nisu pogođeni.
Rate limiting
Svaki odgovor uključuje rate limit headere:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1711900800Kad se prekorači:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 42 seconds."
}
}Response uključuje Retry-After: 42 header.
cURL primeri
search/symptoms
curl "https://api.vitahub.rs/v1/search/symptoms?q=bol%20u%20grudima" \
-H "X-API-Key: YOUR_API_KEY"search/doctors
curl "https://api.vitahub.rs/v1/search/doctors?q=Marko&id=12&level=specijalnost" \
-H "X-API-Key: YOUR_API_KEY"diagnosis-doctor
curl -X POST "https://api.vitahub.rs/v1/diagnosis-doctor" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"patientAge": 35,
"patientGender": "musko",
"diagnosisCode": "I10"
}'symptom-doctor
curl -X POST "https://api.vitahub.rs/v1/symptom-doctor" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"patientAge": 45,
"patientGender": "zenski",
"symptoms": "Imam bol u grudima i nedostatak vazduha"
}'wanted-doctor
curl -X POST "https://api.vitahub.rs/v1/wanted-doctor" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"patientAge": 32,
"patientGender": "musko",
"symptoms": "Vrtoglavica i trnjenje leve ruke vec 2 dana",
"preferredDoctor": { "firstName": "Marko", "lastName": "Markovic" }
}'procedures-doctor
curl -X POST "https://api.vitahub.rs/v1/procedures-doctor" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"patientAge": 40,
"patientGender": "musko",
"procedure": "Kardioloski pregled"
}'VitaHub API v1 — poslednje ažuriranje: april 2026