Every response from the Shogun API — whether successful or not — follows the same JSON envelope and always includes a response_code field. Because Shogun returns 200 OK for many error scenarios (the HTTP transport succeeded, but the banking operation did not), your integration must branch on response_code rather than HTTP status alone.
Response envelope
All Shogun responses share this structure:
{
"status": true,
"response_code": "00",
"message": "Human-readable description",
"data": {}
}
| Field | Type | Description |
|---|
status | boolean | true on success, false on any error |
response_code | string | Machine-readable outcome code — always check this |
message | string | Human-readable description of the outcome |
data | object | null | Response payload on success; null on error |
A 200 OK with response_code: "83" means the HTTP request reached Shogun successfully, but the core banking provider rejected the operation. Always branch your logic on response_code, not HTTP status.
Response codes
| Code | Meaning | Recommended action |
|---|
00 | Success | Proceed normally |
01 | Validation error | Read message to identify the failing field and correct your request |
02 | Missing required field | Supply the missing parameter identified in message |
41 | Unauthorized — invalid API credentials | Verify your client_id and client_secret |
42 | Token expired or invalid | Regenerate your bearer token and retry the request once |
43 | Insufficient permissions | Your API client role does not allow this action — check your granted authorities |
50 | Duplicate request | This record already exists; do not retry |
80 | Service unavailable | The core banking provider is temporarily down — retry with exponential backoff |
83 | Provider error | Identity verification or account creation was rejected by the bank — do not retry without fixing the underlying data |
99 | Internal server error | Contact Shogun support and include the request ID from message |
HTTP status code mapping
Shogun maps response codes to standard HTTP statuses as follows:
| HTTP Status | When |
|---|
200 OK | Request was processed — check response_code for the actual outcome |
400 Bad Request | Malformed request body — the JSON could not be parsed |
401 Unauthorized | Missing or invalid Authorization header |
403 Forbidden | Valid token but insufficient permissions for this endpoint |
404 Not Found | The requested resource does not exist |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | Unexpected server error |
Handling errors in code
The example below shows a production-ready pattern: check status first, then branch on specific response_code values to decide whether to retry, refresh credentials, or surface the error to your system.
import requests
response = requests.post(
"https://api.shogun.io/api/v1/account/api/create_customer_account",
headers={"Authorization": f"Bearer {token}"},
json=payload
)
body = response.json()
if not body["status"]:
code = body["response_code"]
if code == "80":
# Core banking is temporarily down — retry with exponential backoff
pass
elif code == "42":
# Token expired — refresh and retry once
pass
else:
raise Exception(f"API error {code}: {body['message']}")
Rate limits and backoff
Shogun applies per-client rate limits. When you exceed them, you receive a 429 Too Many Requests response:
{
"status": false,
"response_code": "429",
"message": "Request rate limit exceeded. Please slow down."
}
Implement exponential backoff on 429 responses and on response_code: "80" (service unavailable):
- Wait 1 second before the first retry
- Double the wait time on each subsequent attempt: 1s → 2s → 4s → 8s → 16s → 32s
- Stop retrying after 32 seconds and surface the error to your monitoring system
Login and token-generation endpoints are rate-limited separately. Repeated authentication failures trigger a temporary account lockout. Avoid retrying failed token requests in a tight loop.