Skip to content
Partner API Docs

Errors

Every MyStocks Partner API error carries a machine-readable error.code and a human-readable error.message. Full reference of HTTP status codes, error codes, and structured order-rejection codes.

Every error response carries a top-level error object with a machine-readable code string and a human-readable message. This applies to all endpoints. Check error.code for programmatic handling; use error.message for logging or UI display.

// 401 auth error
{ "error": { "code": "AUTH_MISSING", "message": "Provide a valid partner API key via Authorization: Bearer pk_live_... or X-Api-Key header." } }
 
// 400 validation error
{ "error": { "code": "VALIDATION_ERROR", "message": "Ambiguous symbol \"MTN\" matches multiple listings: MTN.GH, MTN.NG. Use an exchange-qualified symbol." } }

HTTP status codes

FieldTypeRequiredDescription
200OKNoRequest succeeded.
201CreatedNoResource created (register, create sub-account).
202AcceptedNoOrder accepted into the live fill flow (trade, subscribe). Funds escrowed immediately; settlement is asynchronous.
400Bad RequestNoMissing or invalid parameters — check the error message.
401UnauthorizedNoAPI key missing, invalid, revoked, or expired.
403ForbiddenNoAction not permitted: account not yet approved, sub-account frozen, or an operation outside your tier.
404Not FoundNoStock symbol, sub-account, holding, or instrument not found.
409ConflictNoIdempotency collision — a concurrent request with the same Idempotency-Key is still in progress. Retry after it resolves.
422UnprocessableNoBusiness-rule violation: insufficient balance, KYC required, frozen sub-account, fund not open, or units exceed holdings.
429Too Many RequestsNoRate limit exceeded. Check X-RateLimit-Remaining and X-RateLimit-Reset headers.
500Internal Server ErrorNoServer-side failure — retry with exponential backoff or contact support.

Machine-readable error codes

When the error field is an object, error.code is one of the values below.

FieldTypeRequiredDescription
AUTH_MISSING401NoNo API key supplied. Send Authorization: Bearer pk_live_... or X-Api-Key.
AUTH_INVALID401NoKey format is wrong or the key does not exist in the registry.
AUTH_SUSPENDED403NoPartner account temporarily suspended. Contact support@mystocks.africa.
AUTH_REVOKED403NoKey permanently revoked. A new key must be issued — revocation cannot be undone.
RATE_LIMITED429NoToo many requests. Back off and retry after X-RateLimit-Reset.
MISSING_PARAM400NoA required query/body parameter is absent. Check error.param or error.params[].
MISSING_IDEMPOTENCY_KEY400NoA money-movement/state-changing POST was sent without the required Idempotency-Key header.
INVALID_SYMBOL400NoSymbol fails format validation (2–20 alphanumerics, optionally dot-separated). Check error.invalid[] in a batch.
UNKNOWN_EXCHANGE400NoExchange code not recognised. See the supported codes list.
INVALID_TYPE400NoA parameter has the wrong type.
VALIDATION_ERROR400NoRequest body or query param failed validation. See error.message.
BATCH_LIMIT_EXCEEDED400NoBatch exceeds the max symbol count. Check error.max and error.received.
NOT_FOUND404NoRequested resource does not exist.
CONFLICT409NoConcurrent request conflict: idempotency collision or order state changed mid-operation.
QUOTE_REQUIRED400NoNo quoteId supplied on a trade. Every trade needs a fresh single-use quoteId from GET /quote/{symbol}.
QUOTE_NOT_FOUND404NoquoteId never issued, or already expired and garbage-collected. Fetch a fresh quote.
QUOTE_SCOPE_MISMATCH403NoquoteId belongs to a different account context. Fetch with the same subAccountId you trade on.
STALE_QUOTE409NoquoteId expired (60s TTL) or already used. Fetch a fresh quote and retry.
QUOTE_ORDER_MISMATCH409NoquoteId does not match the submitted symbol/side/quantity/cashValue. Request a new quote.
INSUFFICIENT_FUNDS400NoWallet balance too low. Top up the master wallet or deposit into the sub-account first.
KYC_REQUIRED403NoSub-account KYC not verified. Assert via POST /users/{userId}/kyc then retry.
FORBIDDEN403NoAuthenticated but not authorised (e.g. read-only data key on a write endpoint).
INTERNAL_ERROR500NoUnexpected server-side failure. Safe to retry with backoff.

Order rejection codes

When an order moves to REJECTED, both the order.rejected webhook and GET /orders/{orderId} include a structured rejectionCode alongside the free-text rejectionReason.

FieldTypeRequiredDescription
INSUFFICIENT_FUNDSstringNoWallet had insufficient balance at time of review.
KYC_REQUIREDstringNoSub-account KYC not verified. Assert via POST /users/{userId}/kyc before retrying.
MARKET_CLOSEDstringNoExchange was closed or on a public holiday when the order was reviewed.
COMPLIANCE_HOLDstringNoOrder flagged for compliance review. Contact support.
TECHNICAL_ISSUEstringNoA technical issue prevented execution. Safe to retry.
OTHERstringNoReason does not fit a standard code — see rejectionReason.

On this page