Errors

The OneFinOps API returns a flat error body on every 4xx / 5xx response. The contract is additive-only — we won't break a code you depend on, and we'll only ever add fields.

The body

{
  "code": "382",
  "message": "NIC 382: You Cannot Extend as EWB can be Extended only 8 hour before or after w.r.t Validity of EWB",
  "details": {
    "382": [
      "You Cannot Extend as EWB can be Extended only 8 hour before or after w.r.t Validity of EWB"
    ]
  },
  "requestId": "8c2b5…",
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-…-01",
  "timestamp": "2026-05-21T10:32:18.000Z"
}
FieldUse
codeBranch on this. Never on message. For NIC business errors this is the NIC numeric code (e.g. "382"); for OneFinOps-side errors it is a dotted identifier (e.g. einvoice.cancel_window_expired).
messageShow to humans. Never to programmatic logic.
detailsOptional. Keys are error codes (or field paths on 422 validation failures); values are arrays of messages. For NIC errors the verbatim NIC text is preserved here under the NIC code key.
requestIdEcho of the X-Request-Id you sent (or one OneFinOps generated). Quote it when filing a support ticket.
traceIdDistributed-tracing id (W3C traceparent). Useful when escalating to support.
timestampUTC time the error was generated.

The HTTP status is the source of truth for the error category — there is no httpStatus field in the body. NIC and gateway names never appear on the wire; the public surface only ever mentions "NIC" and "GST".

Status families

HTTPWhat it meansRetry?
400Request was malformed (bad JSON, syntactically invalid).No — fix the body.
401Token missing, expired, or for the wrong environment.After re-auth.
403Token is fine; plan / entitlement doesn't permit this call.No — contact your account manager.
404Resource doesn't belong to your tenant or doesn't exist.No.
409State conflict — cancel window expired, duplicate replay with different body, etc.No (state-bound).
422Body, query, or upstream NIC business rule failed. Inspect details.No — fix the input or wait for the NIC condition to clear.
429Rate limited.Yes, with backoff.
502Upstream gateway unreachable.Yes, with backoff.
503NIC briefly unavailable.Yes, with backoff.
504NIC timed out.Yes, with backoff.
5xx (other)OneFinOps-side issue.Yes, with backoff. Surface to support if persistent.

Common codes (any endpoint)

CodeHTTPMeaning
validation_error422Body or query failed validation. Inspect details.
not_found404Resource doesn't exist or isn't visible to your tenant.
conflict409State conflict.
gstin.required400gstin header is required for this endpoint and was missing or empty.
auth.invalid_token401Token missing, malformed, or expired.
auth.entitlement_missing403Plan doesn't include the capability you called.
request.rejected429Rate limited.
GSP_GATEWAY_REJECT422Upstream gateway rejected the call for a non-NIC reason (e.g. credential cache miss). message carries the verbatim upstream text.

E-Invoice codes

CodeHTTPMeaning
irp_credentials.not_configured400No IRP credential uploaded for the seller GSTIN.
einvoice.cancel_window_expired409IRN is past NIC's 24-hour cancellation window.
einvoice.not_cancellable409IRN is in a state that doesn't permit cancellation.
einvoice.invalid_id400irn is not a 64-character hex string.
EInvoice.Signature.CertNotConfigured500Signed-JWS decode requested but the NIC IRP public certificate is not configured on the server.

NIC IRP also returns its own numeric codes for business rejections — 2150 (Duplicate IRN), 2163 (Document date should not be a future date), etc. These come through as the top-level code directly, with the verbatim NIC message in details.

E-Way Bill codes

CodeHTTPMeaning
ewb_credentials.not_configured400No EWB-portal credential uploaded for the supplier GSTIN.
ewaybill.not_cancellable409EWB is past the 24-hour cancel window or NIC has marked movement as begun.
ewaybill.validity_expired409Tried to extend or update Part-B on an EWB outside its extension window.
ewaybill.invalid_number400ewbNumber is not a 12-digit number.

NIC EWB also returns its own numeric codes — 382 (extend outside ±8h window), 328 (transporter details unavailable), 2230 (cannot cancel an EWB linked to an IRN), etc. These come through as the top-level code directly.

NIC business errors

When NIC rejects a call for a domain reason — duplicate IRN, expired cancel window, validity edge cases, suspended GSTIN, etc. — the response is HTTP 422 with the NIC code in the top-level code field and the verbatim NIC text in details["<code>"]. The message field combines "NIC <code>: <text>" for human display.

Branch on code. Surface message (or details["<code>"]) verbatim to the end user when helpful — it's the same text NIC's portals show.

{
  "code": "2150",
  "message": "NIC 2150: Duplicate IRN",
  "details": { "2150": ["Duplicate IRN"] }
}

Retry policy

429 / 502 / 503 / 504   → exponential backoff with jitter (1s → 2s → 4s → 8s, capped 30s).
422 (NIC code)          → DO NOT retry blindly. Read the NIC code first; most
                          indicate a data problem that retrying won't fix.
                          Specific 422s like GSP_GATEWAY_REJECT "Invalid Token"
                          are transient and may be retried once.
4xx (other)             → fix the input first; the request needs to change.
5xx (other, OneFinOps)  → exponential backoff; escalate if persistent.

NIC IRP is itself idempotent on (sellerGstin, documentType, documentNumber, financialYear). If you re-submit the same tuple, NIC returns the existing IRN with code 2150 and message "Duplicate IRN" — see Generate an IRN — duplicate detection.

Where to next