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);
}