Error Codes Catalog Bilko Error Codes Catalog Project: Bilko Version: 1.0 Date: 2026-02-24 Status: Specification Applies to: apps/api/ — all modules Overview All Bilko API errors follow a consistent JSON structure. Every error response includes: An HTTP status code A machine-readable BILKO-XXXX error code A human-readable message (in the organization's configured language) Optional field-level details for validation errors Error code ranges by module: Range Module BILKO-1xxx Authentication BILKO-2xxx Organizations BILKO-3xxx Invoices BILKO-4xxx Expenses BILKO-5xxx Banking BILKO-6xxx Reports BILKO-7xxx Contacts BILKO-8xxx Settings & Accounts BILKO-9xxx General / Cross-cutting Error Response Schema All error responses use this structure: interface ErrorResponse { error: { code: string // e.g., "BILKO-1001" message: string // Human-readable, localized details?: Record // Field-level validation errors (422 only) requestId?: string // Trace ID for support (production) } } Examples: // Authentication error { "error": { "code": "BILKO-1001", "message": "Pogrešan email ili lozinka.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } // Validation error (422) with field details { "error": { "code": "BILKO-9003", "message": "Validacija nije uspjela.", "details": { "email": ["Email adresa nije ispravna."], "password": ["Lozinka mora imati najmanje 8 znakova.", "Lozinka mora sadržavati barem jedan broj."] }, "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } HTTP Status Codes HTTP Code Meaning When Used 200 OK Successful read or update GET, PUT, PATCH 201 Created Resource successfully created POST (creates new record) 204 No Content Successful deletion DELETE, POST /logout 400 Bad Request Request is well-formed but semantically invalid Business rule violations (not validation) 401 Unauthorized Missing, expired, or invalid authentication No token, expired JWT, wrong credentials 403 Forbidden Authenticated but insufficient permissions Role lacks access to endpoint or action 404 Not Found Resource does not exist within organization scope Record not found or belongs to different org 409 Conflict Resource already exists Duplicate email, duplicate invoice number 413 Payload Too Large Upload exceeds size limit File uploads over 10MB (receipt) or 5MB (CSV) 422 Unprocessable Entity Zod schema validation failed Invalid field types, missing required fields 429 Too Many Requests Rate limit exceeded Auth: 5/min; writes: 10–50/min; reads: 100/min 500 Internal Server Error Unexpected server-side error Unhandled exception, DB error 503 Service Unavailable External dependency unavailable SendGrid, ECB API, Cloudflare R2 down Retry Guidance Error Code HTTP Retry? Strategy BILKO-1003 401 Yes Refresh access token via POST /auth/refresh , then retry BILKO-9005 429 Yes Wait until Retry-After header value (seconds), then retry BILKO-9006 500 Yes Exponential backoff: 1s, 2s, 4s — max 3 retries BILKO-9007 503 Yes Exponential backoff: 2s, 5s, 10s — max 3 retries All 4xx except above — No Fix request before retrying — these are client errors BILKO-1001 401 No Wrong credentials — do not retry automatically BILKO-3011 500 Yes SendGrid transient failure — retry once after 5s Retry-After header: Always present on 429 responses. Value is seconds to wait. Module: Authentication (1xxx) BILKO-1001 — Invalid Credentials Field Value HTTP 401 Trigger POST /auth/login — email not found or password does not match bcrypt hash Retry No { "error": { "code": "BILKO-1001", "message": "Pogrešan email ili lozinka." } } BILKO-1002 — Account Disabled Field Value HTTP 403 Trigger POST /auth/login — user has isActive = false Retry No — contact support { "error": { "code": "BILKO-1002", "message": "Vaš nalog je deaktiviran. Kontaktirajte podršku." } } BILKO-1003 — Access Token Expired Field Value HTTP 401 Trigger Any authenticated request — JWT exp claim is in the past Retry Yes — refresh token first via POST /auth/refresh , then retry original request { "error": { "code": "BILKO-1003", "message": "Sesija je istekla. Osvježite token." } } BILKO-1004 — Invalid Token Field Value HTTP 401 Trigger Any authenticated request — JWT signature invalid or malformed Retry No — re-authenticate { "error": { "code": "BILKO-1004", "message": "Token nije ispravan. Molimo prijavite se ponovo." } } BILKO-1005 — No Authentication Token Field Value HTTP 401 Trigger Any authenticated endpoint called without Authorization: Bearer header Retry No — add token { "error": { "code": "BILKO-1005", "message": "Autentifikacija je obavezna." } } BILKO-1006 — Refresh Token Invalid or Expired Field Value HTTP 401 Trigger POST /auth/refresh — cookie missing, token blacklisted, or expired Retry No — force full re-login { "error": { "code": "BILKO-1006", "message": "Sesija je istekla. Molimo prijavite se ponovo." } } BILKO-1007 — Auth Rate Limit Exceeded Field Value HTTP 429 Trigger POST /auth/login or POST /auth/register — 5+ requests in 60 seconds from same IP Retry Yes — after Retry-After header value (900 seconds / 15 min lockout) { "error": { "code": "BILKO-1007", "message": "Previše pokušaja prijave. Pokušajte ponovo za 15 minuta." } } Response headers: Retry-After: 900 X-RateLimit-Limit: 5 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1740399600 BILKO-1008 — Email Already Registered Field Value HTTP 409 Trigger POST /auth/register — email already exists in users table Retry No — use different email or reset password { "error": { "code": "BILKO-1008", "message": "Email adresa je već registrirana." } } BILKO-1009 — Weak Password Field Value HTTP 422 Trigger POST /auth/register or PUT /auth/password — password fails strength requirements Retry No — fix password { "error": { "code": "BILKO-1009", "message": "Lozinka ne zadovoljava sigurnosne zahtjeve.", "details": { "password": [ "Lozinka mora imati najmanje 8 znakova.", "Lozinka mora sadržavati barem jedno veliko slovo.", "Lozinka mora sadržavati barem jedan broj." ] } } } BILKO-1010 — Two-Factor Authentication Required Field Value HTTP 403 Trigger POST /auth/login — user has twoFactorEnabled = true , 2FA code not provided Retry No — submit TOTP code via POST /auth/verify-2fa { "error": { "code": "BILKO-1010", "message": "Potrebna je dvofaktorska autentifikacija.", "details": { "requiresTwoFactor": ["true"] } } } BILKO-1011 — Invalid 2FA Code Field Value HTTP 401 Trigger POST /auth/verify-2fa — TOTP code incorrect or expired (outside 30s window) Retry No — request new code from authenticator app { "error": { "code": "BILKO-1011", "message": "Kod za verifikaciju nije ispravan ili je istekao." } } BILKO-1012 — Invalid Invite Token Field Value HTTP 401 Trigger User follows invite link after it has expired (7 days) or already been used Retry No — request new invitation { "error": { "code": "BILKO-1012", "message": "Pozivnica je nevažeća ili je istekla." } } Module: Organizations (2xxx) BILKO-2001 — Organization Not Found Field Value HTTP 404 Trigger Organization ID in JWT does not exist in database (account deleted while token still valid) { "error": { "code": "BILKO-2001", "message": "Organizacija nije pronađena." } } BILKO-2002 — Invalid Currency Code Field Value HTTP 422 Trigger PUT /organization — baseCurrency is not one of EUR , RSD , BAM , HRK { "error": { "code": "BILKO-2002", "message": "Neispravna valuta. Podržane valute: EUR, RSD, BAM, HRK.", "details": { "baseCurrency": ["Vrijednost mora biti jedna od: EUR, RSD, BAM, HRK."] } } } BILKO-2003 — Invalid Language Code Field Value HTTP 422 Trigger PUT /organization — language is not one of sr , bs , hr { "error": { "code": "BILKO-2003", "message": "Neispravni jezički kod. Podržani jezici: sr, bs, hr.", "details": { "language": ["Vrijednost mora biti jedna od: sr, bs, hr."] } } } BILKO-2004 — Cannot Change Base Currency Field Value HTTP 400 Trigger PUT /organization — attempting to change baseCurrency when transactions already exist { "error": { "code": "BILKO-2004", "message": "Osnovna valuta ne može se promijeniti jer već postoje finansijske transakcije." } } BILKO-2005 — User Not Found in Organization Field Value HTTP 404 Trigger PUT /users/:id/role or DELETE /users/:id — user UUID not in caller's organization { "error": { "code": "BILKO-2005", "message": "Korisnik nije pronađen u ovoj organizaciji." } } BILKO-2006 — Cannot Modify Owner Field Value HTTP 403 Trigger PUT /users/:id/role or DELETE /users/:id — target user is owner { "error": { "code": "BILKO-2006", "message": "Nije moguće promijeniti ili ukloniti vlasnika organizacije." } } BILKO-2007 — Cannot Remove Self Field Value HTTP 403 Trigger DELETE /users/:id — user attempts to delete their own account { "error": { "code": "BILKO-2007", "message": "Ne možete ukloniti vlastiti korisnički račun." } } BILKO-2008 — Cannot Invite Existing Member Field Value HTTP 409 Trigger POST /users/invite — email already belongs to a user in this organization { "error": { "code": "BILKO-2008", "message": "Korisnik s ovim emailom je već član organizacije." } } Module: Invoices (3xxx) BILKO-3001 — Invoice Not Found Field Value HTTP 404 Trigger GET/PUT/PATCH/DELETE /invoices/:id — ID not found in caller's organization { "error": { "code": "BILKO-3001", "message": "Faktura nije pronađena." } } BILKO-3002 — Customer Not Found Field Value HTTP 404 Trigger POST /invoices — customerId does not exist in organization's contacts { "error": { "code": "BILKO-3002", "message": "Klijent nije pronađen." } } BILKO-3003 — Invoice Not in Draft Status Field Value HTTP 400 Trigger PUT /invoices/:id — attempting to edit an invoice that is not in draft status { "error": { "code": "BILKO-3003", "message": "Faktura se može mijenjati samo u statusu 'nacrt'.", "details": { "status": ["Trenutni status: sent. Samo nacrti se mogu uređivati."] } } } BILKO-3004 — Invalid Invoice Status Transition Field Value HTTP 400 Trigger PATCH /invoices/:id/status — action is not valid for current invoice status Valid transitions: draft → sent (action: send ) sent or viewed → paid (action: mark-paid ) Any non-cancelled → cancelled (action: cancel ) { "error": { "code": "BILKO-3004", "message": "Nevažeća promjena statusa fakture.", "details": { "action": ["Akcija 'mark-paid' nije dozvoljena za status 'draft'."] } } } BILKO-3005 — Customer Has No Email Field Value HTTP 400 Trigger POST /invoices/:id/send — customer contact has no email field set { "error": { "code": "BILKO-3005", "message": "Klijent nema email adresu. Dodajte email u kontakt podatke." } } BILKO-3006 — Invoice Items Required Field Value HTTP 422 Trigger POST /invoices — items array is empty { "error": { "code": "BILKO-3006", "message": "Faktura mora imati najmanje jednu stavku.", "details": { "items": ["Polje items ne može biti prazno."] } } } BILKO-3007 — Negative or Zero Amount Field Value HTTP 422 Trigger POST /invoices or POST /invoices/:id/send — unitPrice or quantity is ≤ 0 { "error": { "code": "BILKO-3007", "message": "Iznosi moraju biti veći od nule.", "details": { "items[0].unitPrice": ["Cijena mora biti pozitivan broj."] } } } BILKO-3008 — Invalid Tax Rate Field Value HTTP 422 Trigger POST /invoices — taxRate is negative or exceeds 100 { "error": { "code": "BILKO-3008", "message": "Stopa poreza mora biti između 0 i 100.", "details": { "items[0].taxRate": ["Vrijednost mora biti između 0 i 100."] } } } BILKO-3009 — Due Date Before Invoice Date Field Value HTTP 422 Trigger POST /invoices — dueDate is before invoiceDate { "error": { "code": "BILKO-3009", "message": "Datum dospijeća ne može biti prije datuma fakture.", "details": { "dueDate": ["Datum dospijeća mora biti isti ili kasniji od datuma fakture."] } } } BILKO-3010 — Invoice PDF Not Available Field Value HTTP 404 Trigger GET /invoices/:id/pdf — PDF has not yet been generated (invoice still in draft ) { "error": { "code": "BILKO-3010", "message": "PDF faktura nije dostupan. Faktura mora biti poslana da bi se generirao PDF." } } BILKO-3011 — Invoice Email Delivery Failed Field Value HTTP 500 Trigger POST /invoices/:id/send — SendGrid API returned error Retry Yes — once, after 5 seconds { "error": { "code": "BILKO-3011", "message": "Slanje emaila nije uspjelo. Pokušajte ponovo.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } Module: Expenses (4xxx) BILKO-4001 — Expense Not Found Field Value HTTP 404 Trigger GET/PUT/PATCH/DELETE /expenses/:id — ID not in caller's organization { "error": { "code": "BILKO-4001", "message": "Troškak nije pronađen." } } BILKO-4002 — Expense Not in Pending Status Field Value HTTP 400 Trigger PUT /expenses/:id or DELETE /expenses/:id — expense is not in pending status { "error": { "code": "BILKO-4002", "message": "Troškak se može mijenjati ili brisati samo u statusu 'na čekanju'.", "details": { "status": ["Trenutni status: approved."] } } } BILKO-4003 — Expense Already Processed Field Value HTTP 400 Trigger PATCH /expenses/:id/approve — expense is already approved , paid , or rejected { "error": { "code": "BILKO-4003", "message": "Troškak je već obrađen i ne može se odobriti ponovo.", "details": { "status": ["Trenutni status: approved."] } } } BILKO-4004 — Vendor Not Found Field Value HTTP 404 Trigger POST /expenses — vendorId not found in organization's contacts { "error": { "code": "BILKO-4004", "message": "Dobavljač nije pronađen." } } BILKO-4005 — Receipt File Too Large Field Value HTTP 413 Trigger POST /expenses with receiptFile — file exceeds 10MB { "error": { "code": "BILKO-4005", "message": "Fajl je prevelik. Maksimalna veličina je 10 MB." } } BILKO-4006 — Invalid Receipt File Type Field Value HTTP 422 Trigger POST /expenses with receiptFile — file is not PDF, PNG, or JPG { "error": { "code": "BILKO-4006", "message": "Neispravni tip fajla. Dozvoljeni formati: PDF, PNG, JPG.", "details": { "receiptFile": ["Tip fajla 'docx' nije dozvoljen."] } } } BILKO-4007 — Receipt Upload Failed Field Value HTTP 500 Trigger Cloudflare R2 upload failed after ClamAV scan passed Retry Yes — exponential backoff { "error": { "code": "BILKO-4007", "message": "Upload računa nije uspio. Pokušajte ponovo.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } BILKO-4008 — File Rejected (Virus Detected) Field Value HTTP 422 Trigger ClamAV scan detected malware in uploaded file Retry No { "error": { "code": "BILKO-4008", "message": "Fajl nije prihvaćen zbog sigurnosnih razloga." } } Module: Banking (5xxx) BILKO-5001 — Bank Account Not Found Field Value HTTP 404 Trigger GET/POST /bank-accounts/:id/* — ID not found in caller's organization { "error": { "code": "BILKO-5001", "message": "Bankovni račun nije pronađen." } } BILKO-5002 — GL Account Must Be Asset Type Field Value HTTP 422 Trigger POST /bank-accounts — referenced accountId is not an Asset account type { "error": { "code": "BILKO-5002", "message": "Konto za bankovni račun mora biti tipa 'Imovina'.", "details": { "accountId": ["Odabrani konto je tipa 'Rashodi'. Odaberite konto tipa 'Imovina'."] } } } BILKO-5003 — GL Account Not Found Field Value HTTP 404 Trigger POST /bank-accounts — accountId does not exist in organization { "error": { "code": "BILKO-5003", "message": "Konto nije pronađen." } } BILKO-5004 — Bank Transaction Not Found Field Value HTTP 404 Trigger POST /bank-accounts/:id/reconcile — bankTransactionId not found { "error": { "code": "BILKO-5004", "message": "Bankovna transakcija nije pronađena." } } BILKO-5005 — Transaction Already Reconciled Field Value HTTP 400 Trigger POST /bank-accounts/:id/reconcile — either transaction is already reconciled = true { "error": { "code": "BILKO-5005", "message": "Transakcija je već usklađena." } } BILKO-5006 — Invalid CSV Format Field Value HTTP 422 Trigger POST /bank-accounts/:id/import — CSV missing required columns or malformed { "error": { "code": "BILKO-5006", "message": "Nevažeći format CSV fajla.", "details": { "file": ["Obavezne kolone: Date, Description, Amount, Reference."] } } } BILKO-5007 — CSV File Too Large Field Value HTTP 413 Trigger POST /bank-accounts/:id/import — CSV file exceeds 5MB { "error": { "code": "BILKO-5007", "message": "CSV fajl je prevelik. Maksimalna veličina je 5 MB." } } BILKO-5008 — Invalid CSV Date Format Field Value HTTP 422 Trigger POST /bank-accounts/:id/import — date column values not parseable as ISO 8601 { "error": { "code": "BILKO-5008", "message": "Nevažeći format datuma u CSV fajlu.", "details": { "file": ["Datumi moraju biti u formatu YYYY-MM-DD (npr. 2026-02-24)."] } } } Module: Reports (6xxx) BILKO-6001 — From Date Required Field Value HTTP 422 Trigger GET /reports/profit-loss , /cash-flow , /vat — from query parameter missing { "error": { "code": "BILKO-6001", "message": "Početni datum je obavezan.", "details": { "from": ["Parametar 'from' je obavezan."] } } } BILKO-6002 — To Date Required Field Value HTTP 422 Trigger GET /reports/profit-loss , /cash-flow , /vat — to query parameter missing { "error": { "code": "BILKO-6002", "message": "Krajnji datum je obavezan.", "details": { "to": ["Parametar 'to' je obavezan."] } } } BILKO-6003 — Invalid Date Range Field Value HTTP 422 Trigger Any report endpoint — from date is after to date { "error": { "code": "BILKO-6003", "message": "Nevažeći raspon datuma. Početni datum mora biti prije krajnjeg.", "details": { "from": ["Mora biti prije 'to' datuma."] } } } BILKO-6004 — Trial Balance Not Balanced Field Value HTTP 500 Trigger GET /reports/trial-balance — internal data integrity check failed (debit ≠ credit totals) Retry No — requires manual investigation { "error": { "code": "BILKO-6004", "message": "Greška integriteta podataka: probni bilans nije uravnotežen. Kontaktirajte podršku.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } Module: Contacts (7xxx) BILKO-7001 — Contact Not Found Field Value HTTP 404 Trigger GET/PUT/DELETE /contacts/:id — ID not found in caller's organization { "error": { "code": "BILKO-7001", "message": "Kontakt nije pronađen." } } BILKO-7002 — Contact Has Active Invoices Field Value HTTP 400 Trigger DELETE /contacts/:id — contact has invoices with status other than cancelled { "error": { "code": "BILKO-7002", "message": "Kontakt ne može biti deaktiviran jer ima aktivne fakture." } } BILKO-7003 — Contact Has Active Expenses Field Value HTTP 400 Trigger DELETE /contacts/:id — contact has expenses with status other than rejected { "error": { "code": "BILKO-7003", "message": "Kontakt ne može biti deaktiviran jer ima aktivne troškove." } } BILKO-7004 — Invalid ISO Country Code Field Value HTTP 422 Trigger POST/PUT /contacts — country is not a valid ISO 3166-1 alpha-2 code { "error": { "code": "BILKO-7004", "message": "Nevažeći kod države.", "details": { "country": ["Mora biti ISO 3166-1 alpha-2 kod (npr. 'RS', 'BA', 'HR')."] } } } BILKO-7005 — Invalid Payment Terms Field Value HTTP 422 Trigger POST/PUT /contacts — paymentTerms is negative or not an integer { "error": { "code": "BILKO-7005", "message": "Rok plaćanja mora biti pozitivan cijeli broj (dani).", "details": { "paymentTerms": ["Mora biti pozitivni cijeli broj."] } } } Module: Settings & Accounts (8xxx) BILKO-8001 — Account Not Found Field Value HTTP 404 Trigger PUT /accounts/:id — account UUID not found in caller's organization { "error": { "code": "BILKO-8001", "message": "Konto nije pronađen." } } BILKO-8002 — Account Code Already Exists Field Value HTTP 409 Trigger POST /accounts — code is not unique within the organization { "error": { "code": "BILKO-8002", "message": "Konto sa ovim kodom već postoji.", "details": { "code": ["Kod '1200' je već u upotrebi."] } } } BILKO-8003 — Invalid Account Type Field Value HTTP 422 Trigger POST /accounts — accountTypeId is not 1–5 { "error": { "code": "BILKO-8003", "message": "Nevažeći tip konta.", "details": { "accountTypeId": ["Mora biti između 1 (Imovina) i 5 (Rashodi)."] } } } BILKO-8004 — Cannot Deactivate Account with Transactions Field Value HTTP 400 Trigger PUT /accounts/:id — setting isActive = false on account that has transactions { "error": { "code": "BILKO-8004", "message": "Konto se ne može deaktivirati jer ima postojeće transakcije." } } BILKO-8005 — Parent Account Not Found Field Value HTTP 404 Trigger POST /accounts — parentAccountId not found in organization { "error": { "code": "BILKO-8005", "message": "Nadređeni konto nije pronađen." } } BILKO-8006 — Invalid VAT Rate Field Value HTTP 422 Trigger PUT /settings/tax-rates — any rate value is negative or exceeds 100 { "error": { "code": "BILKO-8006", "message": "Stopa PDV-a mora biti između 0 i 100.", "details": { "defaultVATRate": ["Vrijednost mora biti između 0 i 100."] } } } General / Cross-cutting (9xxx) BILKO-9001 — Insufficient Permissions Field Value HTTP 403 Trigger Any endpoint — user's role not in allowedRoles for that endpoint { "error": { "code": "BILKO-9001", "message": "Nemate dovoljna prava za ovu akciju.", "details": { "required": ["owner", "admin"], "current": ["accountant"] } } } BILKO-9002 — Resource Not Found Field Value HTTP 404 Trigger Generic fallback when a specific BILKO-Xxxx code doesn't apply { "error": { "code": "BILKO-9002", "message": "Traženi resurs nije pronađen." } } BILKO-9003 — Validation Failed Field Value HTTP 422 Trigger Generic Zod schema validation failure when no specific BILKO-Xxxx code applies { "error": { "code": "BILKO-9003", "message": "Validacija zahtjeva nije uspjela.", "details": { "fieldName": ["Opis greške validacije."] } } } BILKO-9004 — Internal Server Error Field Value HTTP 500 Trigger Unhandled exception; logged to Sentry with full stack trace Retry Yes — exponential backoff { "error": { "code": "BILKO-9004", "message": "Došlo je do greške na serveru. Pokušajte ponovo.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } BILKO-9005 — Rate Limit Exceeded Field Value HTTP 429 Trigger General API rate limit exceeded (100 req/min for reads, 10–50 for writes) Retry Yes — after Retry-After header { "error": { "code": "BILKO-9005", "message": "Previše zahtjeva. Usporite." } } BILKO-9006 — Database Error Field Value HTTP 500 Trigger Prisma throws unexpected DB error (connection lost, constraint violation from race condition) Retry Yes — exponential backoff { "error": { "code": "BILKO-9006", "message": "Greška baze podataka. Pokušajte ponovo.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } BILKO-9007 — External Service Unavailable Field Value HTTP 503 Trigger SendGrid, Cloudflare R2, or ECB API is unreachable after internal retries exhausted Retry Yes — exponential backoff; 503 responses include Retry-After { "error": { "code": "BILKO-9007", "message": "Vanjska usluga trenutno nije dostupna. Pokušajte ponovo za nekoliko minuta.", "requestId": "req_01H9X3K5P2M7N8Q4R6S9T0V1W2" } } BILKO-9008 — Invalid Pagination Parameters Field Value HTTP 400 Trigger Any list endpoint — page < 1 , perPage > 100 , or non-integer values { "error": { "code": "BILKO-9008", "message": "Nevažeći parametri paginacije.", "details": { "perPage": ["Maksimalna vrijednost je 100."], "page": ["Mora biti pozitivan cijeli broj."] } } } i18n Error Messages All error message fields are returned in the organization's configured language ( sr , bs , hr , en ). Codes and details keys are always in English to enable programmatic handling. Message localization table (selected codes): Code SR (Serbian) BS (Bosnian) HR (Croatian) EN (English) BILKO-1001 Pogrešan email ili lozinka. Pogrešan email ili lozinka. Pogrešan email ili lozinka. Invalid email or password. BILKO-1003 Sesija je istekla. Osvježite token. Sesija je istekla. Osvježite token. Sesija je istekla. Osvježite token. Session expired. Please refresh your token. BILKO-1005 Autentifikacija je obavezna. Autentifikacija je obavezna. Autentifikacija je obavezna. Authentication is required. BILKO-1007 Previše pokušaja prijave. Pokušajte za 15 min. Previše pokušaja prijave. Pokušajte za 15 min. Previše pokušaja prijave. Pokušajte za 15 min. Too many login attempts. Try again in 15 minutes. BILKO-1008 Email adresa je već registrirana. Email adresa je već registrirana. Email adresa je već registrirana. Email address is already registered. BILKO-3001 Faktura nije pronađena. Faktura nije pronađena. Faktura nije pronađena. Invoice not found. BILKO-4001 Troškak nije pronađen. Troškak nije pronađen. Trošak nije pronađen. Expense not found. BILKO-7001 Kontakt nije pronađen. Kontakt nije pronađen. Kontakt nije pronađen. Contact not found. BILKO-9001 Nemate dovoljna prava za ovu akciju. Nemate dovoljna prava za ovu akciju. Nemate dovoljna prava za ovu akciju. You do not have permission to perform this action. BILKO-9003 Validacija zahtjeva nije uspjela. Validacija zahtjeva nije uspjela. Provjera zahtjeva nije uspjela. Request validation failed. BILKO-9004 Došlo je do greške na serveru. Došlo je do greške na serveru. Došlo je do pogreške na poslužitelju. An internal server error occurred. BILKO-9005 Previše zahtjeva. Usporite. Previše zahtjeva. Usporite. Previše zahtjeva. Usporite. Too many requests. Please slow down. Implementation: Error messages are stored in /src/lib/i18n/errors/ with one file per language ( sr.json , bs.json , hr.json , en.json ). The message is selected using the organization's language field from the JWT orgId lookup. // src/lib/i18n/errors/en.json (excerpt) { "BILKO-1001": "Invalid email or password.", "BILKO-1003": "Session expired. Please refresh your token.", "BILKO-9001": "You do not have permission to perform this action." } // src/lib/error-formatter.ts function formatError(code: string, orgLanguage: string, details?: Record) { const messages = require(`./i18n/errors/${orgLanguage}.json`) return { error: { code, message: messages[code] ?? messages['BILKO-9004'], ...(details && { details }), } } } Quick Reference — All Error Codes Code HTTP Module Short Description BILKO-1001 401 Auth Invalid credentials BILKO-1002 403 Auth Account disabled BILKO-1003 401 Auth Access token expired BILKO-1004 401 Auth Invalid token BILKO-1005 401 Auth No token provided BILKO-1006 401 Auth Refresh token invalid/expired BILKO-1007 429 Auth Auth rate limit exceeded BILKO-1008 409 Auth Email already registered BILKO-1009 422 Auth Weak password BILKO-1010 403 Auth 2FA required BILKO-1011 401 Auth Invalid 2FA code BILKO-1012 401 Auth Invalid invite token BILKO-2001 404 Org Organization not found BILKO-2002 422 Org Invalid currency code BILKO-2003 422 Org Invalid language code BILKO-2004 400 Org Cannot change base currency BILKO-2005 404 Org User not found in org BILKO-2006 403 Org Cannot modify owner BILKO-2007 403 Org Cannot remove self BILKO-2008 409 Org User already a member BILKO-3001 404 Invoices Invoice not found BILKO-3002 404 Invoices Customer not found BILKO-3003 400 Invoices Invoice not in draft BILKO-3004 400 Invoices Invalid status transition BILKO-3005 400 Invoices Customer has no email BILKO-3006 422 Invoices Items array empty BILKO-3007 422 Invoices Negative/zero amount BILKO-3008 422 Invoices Invalid tax rate BILKO-3009 422 Invoices Due date before invoice date BILKO-3010 404 Invoices PDF not available BILKO-3011 500 Invoices Email delivery failed BILKO-4001 404 Expenses Expense not found BILKO-4002 400 Expenses Expense not pending BILKO-4003 400 Expenses Expense already processed BILKO-4004 404 Expenses Vendor not found BILKO-4005 413 Expenses Receipt file too large BILKO-4006 422 Expenses Invalid file type BILKO-4007 500 Expenses Upload failed BILKO-4008 422 Expenses Virus detected in file BILKO-5001 404 Banking Bank account not found BILKO-5002 422 Banking GL account must be Asset type BILKO-5003 404 Banking GL account not found BILKO-5004 404 Banking Bank transaction not found BILKO-5005 400 Banking Transaction already reconciled BILKO-5006 422 Banking Invalid CSV format BILKO-5007 413 Banking CSV file too large BILKO-5008 422 Banking Invalid CSV date format BILKO-6001 422 Reports From date required BILKO-6002 422 Reports To date required BILKO-6003 422 Reports Invalid date range BILKO-6004 500 Reports Trial balance not balanced BILKO-7001 404 Contacts Contact not found BILKO-7002 400 Contacts Contact has active invoices BILKO-7003 400 Contacts Contact has active expenses BILKO-7004 422 Contacts Invalid country code BILKO-7005 422 Contacts Invalid payment terms BILKO-8001 404 Accounts Account not found BILKO-8002 409 Accounts Account code already exists BILKO-8003 422 Accounts Invalid account type BILKO-8004 400 Accounts Cannot deactivate account with transactions BILKO-8005 404 Accounts Parent account not found BILKO-8006 422 Settings Invalid VAT rate BILKO-9001 403 General Insufficient permissions BILKO-9002 404 General Resource not found BILKO-9003 422 General Validation failed BILKO-9004 500 General Internal server error BILKO-9005 429 General Rate limit exceeded BILKO-9006 500 General Database error BILKO-9007 503 General External service unavailable BILKO-9008 400 General Invalid pagination parameters End of Error Codes Catalog