V
VitaHub API Docs

VitaHub API v1

Preporuka i pretraga doktora na osnovu dijagnoze, simptoma, procedure ili imena.

Base URL:https://api.vitahub.rs

Search / Autocomplete:

Autentifikacija

Svaki zahtev mora sadržati API ključ. Bez validnog ključa API vraća 401.

Obavezan header:

http
X-API-Key: <vas_api_kljuc>

Zajednička pravila

Ova polja važe za sva četiri endpointa:

PoljeTipObaveznoNapomena
patientGenderstringDamuski, musko, m, male, zenski, zensko, z, female
patientAgenumberUslovnoGodine. Obavezno ako nema patientMonths
patientMonthsnumberUslovnoMeseci. Obavezno ako nema patientAge
desiredLocationstringNeŽeljeni grad/region
preferredLanguagesstring[]Nenpr. ["srpski", "engleski"]

Recommendation objekat

Kad bilo koji endpoint vrati doktore, svaki element u data.recommendations[] ima ovaj oblik:

json
{
  "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

LevelZnačenjePrimer
specialtySpecijalnostInterna medicina
subspecialtySubspecijalnostKardiologija
narrowSubspecialtyUža subspecijalizacijaInterventna kardiologija

Samo nivoi koji postoje za datog doktora se vraćaju. Doktor sa jednom specijalnošću ima niz od jednog objekta.

GET

/v1/search/diagnoses

Autocomplete pretraga MKB-10 dijagnoza. Koristi rezultat kao diagnosisCode u diagnosis-doctor.

Request

http
GET /v1/search/diagnoses?q=hipert&limit=5
PoljeTipObaveznoNapomena
qstringDaSearch term, min 2 karaktera
limitnumberNeDefault: 10, max: 50

Response — 200

json
{
  "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
  }
}
GET

/v1/search/procedures

Autocomplete pretraga medicinskih procedura. Svaki rezultat se može direktno proslediti kao element searchItems u procedures-doctor.

Request

http
GET /v1/search/procedures?q=CT%20grudnog
PoljeTipObaveznoNapomena
qstringDaSearch term, min 2 karaktera
limitnumberNeDefault: 10, max: 50

Response — 200

json
{
  "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
  }
}
GET

/v1/search/specialties

Autocomplete pretraga specijalnosti na sva tri nivoa. Svaki rezultat se može proslediti kao element specialtyItems u procedures-doctor.

Request

http
GET /v1/search/specialties?q=kardio
PoljeTipObaveznoNapomena
qstringDaSearch term, min 2 karaktera
limitnumberNeDefault: 10, max: 50

Response — 200

json
{
  "success": true,
  "data": {
    "results": [
      {
        "id": 12,
        "name": "Kardiologija",
        "level": "subspecialty"
      },
      {
        "id": 45,
        "name": "Interventna kardiologija",
        "level": "narrowSubspecialty"
      }
    ],
    "totalFound": 2
  }
}
GET

/v1/search/symptoms

Autocomplete pretraga simptoma. Rezultat se može koristiti za poboljšanje korisničkog unosa pre poziva symptom-doctor endpointa.

Request

http
GET /v1/search/symptoms?q=bol%20u%20grudima
PoljeTipObaveznoNapomena
qstringDaSearch term, min 3 karaktera
limitnumberNeDefault: 10, max: 50

Response — 200

json
{
  "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).

GET

/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

http
GET /v1/search/doctors?q=Marko&id=12&level=specijalnost
PoljeTipObaveznoNapomena
qstringDaIme ili prezime doktora, min 2 karaktera
idnumberUslovnoID specijalnosti — obavezan ako je level prosleđen
levelstringUslovno"specijalnost" | "subspecijalnost" — obavezan ako je id prosleđen
limitnumberNeDefault: 10, max: 50

Parametri id i level su par — ako se prosledi jedan, mora i drugi. Inače API vraća 400.

Response — 200

json
{
  "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)

http
GET /v1/search/doctors?q=Marko&id=12&level=subspecijalnost

Vraća samo doktore čije ime sadrži "Marko" i koji imaju subspecijalnost sa ID-jem 12.

POST

/v1/diagnosis-doctor

Preporuka doktora na osnovu MKB dijagnoze.

Request

json
{
  "patientAge": 35,
  "patientGender": "musko",
  "diagnosisCode": "I10",
  "desiredLocation": "Beograd",
  "preferredLanguages": ["srpski", "engleski"],
  "page": 1,
  "limit": 10
}
PoljeTipObaveznoNapomena
diagnosisCodestringDaMKB-10 kod (npr. I10)
pagenumberNeDefault: 1
limitnumberNeDefault: 10

+ sva zajednička polja

Response — 200

json
{
  "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
  }
}
POST

/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

json
{
  "patientAge": 45,
  "patientGender": "zenski",
  "symptoms": "Imam jak bol u grudima koji se siri u levu ruku.",
  "desiredLocation": "Novi Sad",
  "preferredLanguages": ["engleski"]
}
PoljeTipObaveznoNapomena
symptomsstringDaSlobodan opis simptoma

Request — follow-up (sa odgovorima)

json
{
  "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

json
{
  "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

json
{
  "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."
      }
    ]
  }
}
POST

/v1/wanted-doctor

Pretraga konkretnog doktora + fallback preporuke ako nije dobar match.

Request

json
{
  "patientAge": 32,
  "patientGender": "musko",
  "symptoms": "Vrtoglavica i trnjenje leve ruke vec 2 dana",
  "desiredLocation": "Beograd",
  "preferredLanguages": ["srpski"],
  "preferredDoctor": {
    "firstName": "Marko",
    "lastName": "Markovic",
    "specialization": "neurolog"
  }
}
PoljeTipObaveznoNapomena
symptomsstringDaMin 10 karaktera
preferredDoctorobjectNefirstName, lastName, opciono specialization

Mogući statusi

StatusOpis
NEEDS_MORE_INFOPotrebna su dodatna pitanja
WANTED_DOCTOR_MATCHTačan match, doktor može da pomogne
MORE_THAN_ONE_WANTED_DOCTOR_MATCHViše doktora odgovara imenu
WANTED_DOCTOR_MISMATCHDoktor pronađen ali nije odgovarajuć za problem
DOCTOR_NOT_FOUNDDoktor nije u VitaHub sistemu

Response — WANTED_DOCTOR_MATCH

json
{
  "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

json
{
  "success": true,
  "status": "DOCTOR_NOT_FOUND",
  "message": "Trenutno doktor kog ste trazili nije deo VitaHub sistema."
}
POST

/v1/procedures-doctor

Pretraga doktora po medicinskoj proceduri. Podržava slobodan tekst ili strukturirane stavke.

Request — slobodan tekst

json
{
  "patientAge": 40,
  "patientGender": "musko",
  "desiredLocation": "Beograd",
  "preferredLanguages": ["srpski"],
  "procedure": "Kardioloski pregled",
  "page": 1,
  "limit": 10
}

Request — strukturirane stavke

json
{
  "patientAge": 40,
  "patientGender": "musko",
  "searchItems": [
    {
      "id": 101,
      "name": "CT grudnog kosa",
      "level": "diagnostic",
      "isExamination": false
    }
  ],
  "specialtyItems": [
    {
      "id": 12,
      "name": "Radiologija",
      "level": "specialty"
    }
  ]
}
PoljeTipObaveznoNapomena
procedurestringUslovnoObavezno ako nema searchItems
searchItemsarrayUslovnoObavezno ako nema procedure
specialtyItemsarrayNeOpcioni filter po specijalnosti
pagenumberNeDefault: 1
limitnumberNeDefault: 10

searchItems objekat:

PoljeTipObaveznoNapomena
idnumberDaID procedure
namestringDaNaziv procedure
levelstringDanpr. "diagnostic"
isExaminationbooleanDaDa li je pregled

Response — 200

json
{
  "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:

json
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Opis greske."
  },
  "metadata": {
    "timestamp": "2026-03-31T10:00:00.000Z",
    "requestId": "uuid"
  }
}

Error kodovi

HTTPCodeKad se dešava
400VALIDATION_ERRORNedostaju ili nevalidna polja
400MISSING_AGENi patientAge ni patientMonths nisu prosleđeni
400MISSING_SEARCH_INPUTprocedures-doctor: ni procedure ni searchItems
401UNAUTHORIZEDNema API ključa u headeru
401INVALID_API_KEYAPI ključ nije prepoznat ili je istekao
403FORBIDDENValidan ključ ali nema pristup endpointu
404ENDPOINT_NOT_FOUNDPogrešan URL
429RATE_LIMIT_EXCEEDEDPreviše zahteva — poštovati Retry-After header
500INTERNAL_ERRORNeočekivana greška na serveru
502AI_SERVICE_ERRORAI provider (analiza simptoma) privremeno nedostupan
503SERVICE_UNAVAILABLEServer na održavanju ili preopterećen

Validation error detalji

400 greške uključuju specifična polja:

json
{
  "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:

json
{
  "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:

http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1711900800

Kad se prekorači:

json
{
  "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

bash
curl "https://api.vitahub.rs/v1/search/symptoms?q=bol%20u%20grudima" \
  -H "X-API-Key: YOUR_API_KEY"

search/doctors

bash
curl "https://api.vitahub.rs/v1/search/doctors?q=Marko&id=12&level=specijalnost" \
  -H "X-API-Key: YOUR_API_KEY"

diagnosis-doctor

bash
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

bash
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

bash
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

bash
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