Documentation

Error Codes

All API error codes returned by Shernova with HTTP status and meaning.

Error response shape: { "error": "code", "message": "Human readable", "error_code": "SH_xxx", "doc_url": "https://docs.shernova.com/errors/SH_xxx", "request_id": "…" }. Validation failures use validation_error (400).

Stable error_code (SH_xxx)

SHLegacy codeHTTPMeaning
SH_001unauthorized, invalid_credentials, invalid_refresh401Missing or invalid auth
SH_002not_found404Resource not found
SH_003invalid_state400Session not in valid state
SH_004verification_rate_limited, concurrent_limit_exceeded429Rate or concurrency limit
SH_005invalid_phone400Phone validation failed
SH_006gateway_unavailable503No online gateway
SH_007receipt_invalid401Receipt JWT invalid or expired
SH_008signature_not_registered403Android SHA256 not registered
SH_009package_mismatch403Package name mismatch
SH_010insufficient_credits, plan_expired402Billing blocked
SH_013test_mode_only403Endpoint requires sk_test_ / pk_test_
SH_014receipt_already_used409Receipt replay detected
SH_015idempotency_conflict409Idempotency-Key reused with different body

4xx Client Errors

HTTPCodeDescription
400invalid_phonePhone number failed normalization/validation
400invalid_stateSession not in valid state for action (cancel)
400invalid_rangeAnalytics date range invalid (0–90 days)
400invalid_organizationMalformed X-Shernova-Organization-Id
400invalid_invitationInvitation expired or invalid
400owner_protectedCannot change/remove organization owner
400invalid_requestInvalid billing request (e.g. non-positive credits)
400invalid_webhook_urlWebhook URL malformed
400webhook_https_requiredWebhook URL must use HTTPS
400webhook_private_addressWebhook URL resolves to a private/reserved address
400validation_errorRequest body failed Zod schema validation
401unauthorizedMissing or invalid auth token/key
401invalid_credentialsWrong email/password on login
401invalid_refreshRefresh token invalid or already used
402plan_expiredApplication plan has expired
402insufficient_creditsNo available credits for verification
403account_inactiveDeveloper account disabled
403forbiddenInsufficient permission for resource
403app_disabledApplication is disabled
403app_frozenApplication billing frozen by admin
403package_mismatchSDK package_name doesn't match registered app
403signature_not_registeredAndroid SHA256 not registered
403test_mode_onlyLive key used where test keys are required (SH_013)
404not_foundResource not found
404organization_not_foundNo active organization for user
409email_existsEmail already registered
409member_existsUser already organization member
409gateway_number_mismatchGateway heartbeat number mismatch
409last_adminCannot demote last platform admin
409self_protectedCannot remove own admin access
409receipt_already_usedReceipt JWT already verified (replay)
409idempotency_conflictIdempotency-Key conflict
401receipt_invalidReceipt JWT malformed or expired
422webhook_redirectWebhook URL redirected (not allowed)
422webhook_rejectedWebhook endpoint rejected request
422webhook_dns_failedWebhook hostname DNS lookup failed
422webhook_connection_failedCould not connect to webhook URL
429concurrent_limit_exceededToo many waiting sessions for app

5xx Server Errors

HTTPCodeDescription
502email_delivery_failedInvitation email could not be sent
503gateway_unavailableNo online gateway for verification
503email_not_configuredEmail service not configured
504webhook_timeoutWebhook test timed out (10s)
500internal_errorUnhandled server error

Include request_id when contacting support — it appears in API logs.