Error Codes

Complete reference of error responses returned by the surstrom API.

HTTP Status Codes

CodeMeaning
200Success
204Silent success (SDK endpoints)
400Bad request — validation error or client misconfiguration
401Unauthorized — missing or invalid authentication
403Forbidden — wrong role or account status
429Rate limited — too many requests
500Internal server error
502Provider error — upstream provider failure
503Service unavailable — no providers in pool

Authentication Errors

ErrorStatusDescription
API key required401No x-api-key header provided
Invalid API key format401Key is not a valid UUID
API key not found401No matching key in database
API key owner must be CLIENT403Only CLIENT accounts can use API keys
Account not active403Account is suspended or rejected
Unauthorized401No valid session cookie
Forbidden403Wrong role for the endpoint

General Request Errors

ErrorStatusDescription
Invalid JSON body400Request body is not valid JSON
Internal server error500Unexpected server error

Payment Validation Errors

Returned as { "error": "Validation failed", "details": [...] } with status 400.

FieldErrorDescription
amountrequiredAmount not provided
amountmust be between 2 and 1000Out of valid range
amountmax 2 decimal placesToo many decimal places
maxFeerequiredmaxFee not provided
maxFeemust be a non-negative numberInvalid fee value
maxFeemax 2 decimal placesToo many decimal places
currencyrequiredCurrency not provided
currencymust be usdOnly USD supported currently
externalIdrequiredExternal ID not provided
externalIdmax 36 charactersToo long
externalIdonly Latin letters, digits, - and _ allowedInvalid characters
suffixClientmust be exactly 4 charactersWrong length
suffixClientLatin letters onlyNon-Latin characters
suffixClientblocked valueReserved suffix (test, demo, fake, tmp, temp, dev, debug, mock, stub, foo, bar, baz, xxx, zzz, aaa, asdf, qwer)
thememust be light or darkInvalid theme value

Payment Routing Errors

ErrorStatusDescription
No providers available503No matching provider found
Client withdraw address not configured400Client hasn't set withdraw address
maxFee too low to cover referral fees400Referral fees exceed maxFee
Payment creation failed502All provider attempts failed
Referrer wallet/fee count mismatch400Referral configuration error

No Provider Reasons

When the error is No providers available, the reason field explains:

ReasonDescription
no_providers_in_poolNo providers are currently in the pool
currency_mismatchNo providers support the requested currency
fee_too_lowClient's maxFee is lower than any provider's fee
amount_out_of_rangePayment amount is outside all providers' min/max range
insufficient_relay_balanceMatching providers don't have enough balance
rejected_by_all_relaysAll matching providers have rejected this client
unknownUnspecified matching failure

Wallet Errors

ErrorStatusDescription
Minimum withdrawal is 2 USDC400Amount below minimum
Max 3 decimal places allowed400Too many decimal places
2FA code required400No TOTP code provided
2FA required4002FA not enabled on account
Invalid 2FA code400Wrong TOTP code
No wallet found400User has no wallet
Withdraw address not set400No withdraw address configured
Invalid Solana address400Address is not a valid Solana pubkey
Cannot withdraw to your own deposit address400Withdraw address same as deposit
Active providers in pool400Must remove providers from pool first
Insufficient available balance400Not enough balance after pending
Balance sync error - contact support400Negative available balance detected

Lookup Errors

ErrorStatusDescription
API key required401No x-api-key header provided
Invalid API key401Key not found or invalid
Payment not found404No matching payment for this user

Webhook Errors

ErrorStatusDescription
Only CLIENT users can use webhooks403Relay tried to set webhook
URL is required400No URL provided
URL must be HTTP or HTTPS400Invalid protocol
Internal URLs are not allowed400Localhost or private IP
Invalid URL format400Unparseable URL
Webhook test failed400Server didn't return 200

Provider Errors

ErrorStatusDescription
Missing required fields400Incomplete connection request
Invalid signature400Tampered account data
This account is already connected by another relay400Duplicate provider account
Invalid publishable key format400Wrong key prefix
Publishable key is required400No publishable key provided
Provider not found404Provider doesn't exist or not owned

Provider Settings Errors

ErrorStatusDescription
Invalid webhook URL400Unparseable webhook URL
Webhook URL must be HTTP or HTTPS400Wrong protocol
Statement suffix must be uppercase...400Only A-Z, 0-9, spaces, dots, hyphens, underscores, and template syntax allowed
Payment description contains invalid characters...400Invalid characters in description
Metadata must be an object400Wrong metadata type
Metadata can have at most 10 keys400Too many metadata keys
Metadata keys must be strings of max 40 characters400Key too long
Metadata keys must be alphanumeric with underscores only400Invalid key format
Metadata values must be strings of max 500 characters400Value too long
Invalid minimum amount400Min amount not a valid number
Invalid maximum amount400Max amount not a valid number
Invalid daily limit400Daily limit not a valid number
Minimum/Maximum amount can have at most 2 decimal places400Too many decimals
Daily limit must be a whole number400Decimals not allowed
Fee must be between 0 and 100400Fee out of range
Fee can have at most 2 decimal places400Too many decimals
Minimum cannot exceed maximum400Invalid range

Provider Delete Errors

ErrorStatusDescription
in_pool400Must remove from pool before deleting
active_payments400Has pending payments (includes count)

SDK Verification Errors

ErrorStatusDescription
URL required400No embed URL provided
Invalid URL format400Unparseable URL
Session expired401Session is invalid
Verification failed500Internal verification error

Rate Limit Response

All rate-limited requests return:

Rate limit responsejson
{
"error": "Too many requests",
"retryAfter": 30
}

With headers:

  • Retry-After: 30 — Seconds until rate limit resets
  • X-RateLimit-Remaining: 0 — Remaining requests in window

Rate Limit Presets

EndpointLimit
Payment init10/second per API key
Auth operations10/minute per IP
Provider operations30/minute per user
Sensitive operations5/minute per user
SDK verification10/minute per user
Balance/transactions30/minute per user
Withdrawal2/minute per user
Pool toggle3/minute per user
TOTP operations5/minute per user
General API100/minute per user

Rate limiting is in-memory per server instance. In a multi-instance deployment, actual limits may be higher than configured values.