Chybové odpovede

HTTP kódy a tvar chybového JSON-u, ktoré API vracia.

Všetky chyby majú konzistentný JSON tvar. Status code určuje kategóriu, error.code konkrétnu príčinu, a error.message je human-readable popis vhodný na log.

Tvar chybovej odpovede

Response bodyjson
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Contact con_aaaaaaaaaaaaaaaaaaaaaaaa not found"
  }
}

Validation errors (422)

Pri VALIDATION_ERROR navyše dostaneš field-by-field detail z Zod-u v poli issues:

Response 422json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": {
      "issues": [
        {
          "path": "email",
          "message": "Must be a valid email address"
        },
        {
          "path": "billing_country",
          "message": "Must be a 2-letter ISO 3166-1 alpha-2 code"
        },
        {
          "path": "line_items.0.quantity",
          "message": "Number must be greater than 0"
        }
      ]
    }
  }
}

HTTP status codes

  • • 200 OK - úspešné GET/PATCH/PUT
  • • 201 Created - úspešné POST (resource vytvorený)
  • • 204 No Content - úspešný DELETE alebo akcia bez obsahu
  • • 400 Bad Request - nesprávne formátovaný JSON v body
  • • 401 Unauthorized - chýbajúci, neplatný, expired alebo revoked API kľúč
  • • 402 Payment Required - prekročená mesačná kvóta plánu
  • • 403 Forbidden - kľúč existuje ale nemá scope (alebo má read_only typ pri write request)
  • • 404 Not Found - entita neexistuje alebo patrí inej organizácii (RLS politika ju maskuje)
  • • 409 Conflict - stav nepovoľuje akciu (napr. mazanie inviced dokumentu)
  • • 413 Payload Too Large - upload prekročil 5 MB
  • • 422 Unprocessable Entity - body neprešiel Zod validáciou
  • • 429 Too Many Requests - rate limit prekročený
  • • 500 Internal Server Error - chyba na našej strane (logujeme do Sentry)
  • • 503 Service Unavailable - plánovaná údržba alebo dependency outage

Kompletný zoznam error.code hodnôt nájdeš v Reference → Chybové kódy.

Error handling pattern

TypeScripttypescript
async function callMonivio(path: string) {
  const res = await fetch(`https://monivio.sk/api/v1${path}`, {
    headers: { Authorization: `Bearer ${process.env.MONIVIO_API_KEY!}` },
  });

  if (res.ok) return res.json();

  const { error } = await res.json();

  // Retryable: rate limit + transient server errors.
  if (res.status === 429 || res.status >= 500) {
    const retryAfter = Number(res.headers.get("Retry-After")) || 5;
    await new Promise((r) => setTimeout(r, retryAfter * 1000));
    return callMonivio(path);
  }

  // Permanent: bubble up so the caller can handle 401/403/404 explicitly.
  throw new MonivioError(error.code, error.message, res.status);
}