Error Bucket¶
This is the one place to check when a request fails. Every error_type below maps to a specific, diagnosable cause and an expected client action — if you hit something not listed here, treat it as a bug report waiting to happen and let us know (api-support@indstocks.com).
Response Shape¶
Most failed requests return an HTTP 4xx/5xx status with this JSON body:
{
"status": "error",
"message": "A human-readable message providing details about the error.",
"error_type": "TokenException"
}
A second, undocumented-by-design error shape also occurs
Some endpoints (observed on Instruments and Market Quotes failures) return a different shape instead: {"message": "...", "success": false} — no status field, no error_type. Don't hard-code a check for status == "error" alone; also handle the case where the body only has message and success: false. Check the HTTP status code first, and fall back to reading whichever of error_type or message is present for the human-readable reason.
General API Errors¶
error_type | HTTP Status | Meaning | Expected client action |
|---|---|---|---|
InputException | 400 | Malformed JSON, missing parameters, or wrong data types. | Read message for specifics; fix the request body/params. Not retryable as-is. |
TokenException | 403 (sometimes 401 — see caveat above) | access_token is invalid, expired, or revoked. | Re-authenticate: generate a new token (dashboard or TOTP) and retry. |
UserException | 403 | The authenticated user can't perform this action — account status or a segment (e.g. F&O) isn't activated. | Not retryable by the client; the user needs to complete onboarding/activation for that segment. |
NotFoundException | 404 | The endpoint or resource (e.g. a specific order ID) doesn't exist. | Check the path/ID. Not retryable as-is. |
MethodNotAllowedException | 405 | Wrong HTTP method for this endpoint (e.g. GET where POST is required). | Fix the method. Not retryable as-is. |
DataException | 400 | Bad market/historical data parameters — invalid timeframe or instrument token. | Check scrip-codes/interval/time range against Historical Data. Not retryable as-is. |
NetworkException | 503 | Temporary issue reaching an upstream service (e.g. an exchange). | Safe to retry after a short delay with backoff. |
GeneralException | 500 | Unexpected server-side error. | Safe to retry once; report if it persists. |
ServiceUnavailableException | 503 | API is temporarily down for maintenance or overloaded. | Retry after a short delay with backoff. |
GatewayTimeoutException | 504 | Timeout communicating with an upstream service. | Safe to retry after a short delay with backoff. |
429 Too Many Requests | 429 | You exceeded a rate limit — see API Conventions for the per-category limits. | Back off and retry with a client-side rate limiter; do not hammer the endpoint. |
Retry guidance¶
- Safe to retry with backoff:
NetworkException,GatewayTimeoutException, any bare5xx, and429(after backing off). - Not retryable as-is:
InputException,TokenException(fix the token first),UserException,NotFoundException,MethodNotAllowedException,DataException— these need the request itself fixed, not a retry. - Never blindly retry order placement. If a place-order call times out or errors, you could end up with a duplicate order. Check Get Order Book (or listen on the Order Updates WebSocket) to confirm the order's actual state before resending.
Token Generation Errors (TOTP)¶
These apply to POST /generate/token only — the TOTP-based token flow. That endpoint uses x-api-key rather than Authorization, so an auth failure here means a bad Client ID, MPIN, or TOTP code — not an expired access_token.
| Situation | Meaning | Expected client action |
|---|---|---|
Wrong mpin | The MPIN doesn't match the account. | Fix the MPIN. Not retryable as-is. |
Wrong or expired totp | The code was mistyped, already used, or generated outside its validity window. Counts toward the lockout. | Wait for the next code from the authenticator app. Never retry the same code. |
| Throttled | You called the endpoint more than once in 60 seconds. | Reuse the token you already hold — see Token lifecycle. |
| Locked out | 5 wrong codes in 15 minutes (15-minute lockout), or 3 lockouts within an hour (1-hour lockout). | Back off for the full window; retrying during a lockout will keep failing. Verify your server clock. |
| Every code rejected, app shows a valid code | Server clock drift — TOTP is time-derived, so a skewed clock produces codes the server won't accept. | Sync the host clock via NTP. |
| TOTP was disabled from the dashboard | The stored secret is deleted and the active token is revoked. | Re-run setup on the website, then generate a fresh token. |
Exact status codes and error_type values here are not yet confirmed
The behavior above is accurate, but the specific HTTP status and error_type returned for each case have not been verified against a live deployment. Don't branch on a specific error_type string for this endpoint yet — read the HTTP status and the message field, and treat any non-2xx as "no new token; back off." We'll pin the exact codes here once confirmed.
A lockout blocks new token generation only. Any access token already issued keeps working until its normal 24-hour expiry — see TOTP limits and lockouts.
Order-Specific Errors (RMS)¶
When an order is rejected, it typically returns an OrderException (400 Bad Request) with one of the following messages from our Risk Management System (RMS). These are free-text message values, not separate error_type codes:
| Message | Meaning |
|---|---|
RMS: Margin exceeds ... | The order requires more margin than is available in the account. |
RMS: Rule: Check ... | A custom risk rule was triggered, preventing the order. |
RMS: Blocked for ... | The account or security is blocked for trading by the RMS team for surveillance reasons. |
The instrument is not tradable. | The specified security is not available for trading in the requested segment. |
The quantity is not a multiple of the lot size. | For F&O instruments, the order quantity must be a multiple of the lot size. |
The price is out of the circuit limit. | The order price is outside the security's daily upper or lower circuit limit. |
Order price must be a multiple of the tick size. | The order price is not a valid multiple of the instrument's minimum price movement (tick size). |
Market orders are blocked for this instrument. | Market orders are disabled for this security, often due to low liquidity. Use a limit order instead. |
The order quantity exceeds the freeze limit. | The order quantity is larger than the maximum allowed for a single order by the exchange. Break it into smaller chunks. |
Position could not be found. | An attempt was made to modify or cancel an order that doesn't exist or has already completed. |
The order is already pending... | The order is already awaiting exchange confirmation, so it can't be modified right now. |
Quick Troubleshooting¶
| Situation | Typical HTTP | What to do |
|---|---|---|
| Every request fails immediately | 403 / 401 | access_token is empty, wrong, or expired — regenerate it. |
| Token stopped working mid-day, well before 24h | 403 | Something replaced or revoked it: another process called /generate/token (only the newest TOTP token stays valid), it was revoked from the dashboard, or TOTP was disabled. See Token lifecycle. |
/generate/token keeps failing | — | Wrong MPIN/TOTP, the 60-second throttle, a lockout, or server clock drift — see Token Generation Errors. |
| One specific request fails | 400 | Read message; check the request body/params against that endpoint's page and the Glossary for correct enum casing. |
| Requests started failing under load | 429 | You hit a rate limit — see API Conventions. |
| Order rejected | 400 (OrderException) | Check the RMS message table above. |
| Intermittent failures, same request otherwise works | 5xx | Transient — retry idempotent reads with backoff; for orders, reconcile via Order Book first. |