Error Handling

All errors follow a consistent format. Every error response includes an error type, a machine-readable code, and a human-readable message.

Error format

{
  "error": {
    "type": "INVALID_REQUEST_ERROR",
    "code": "quote_leverage_below_minimum",
    "message": "Leverage is below the minimum allowed for this market."
  }
}
Field
Type
Description

type

string

Error category (see below)

code

string

Machine-readable error code (snake_case). Use this for programmatic handling

message

string

Human-readable description of the error. Suitable for displaying to end users. Don't parse this — values are duplicated as typed fields under params

params

object

Optional. Structured hint values for codes that carry actionable data. See Errors with hints


Error types

Type
HTTP Statuses
Description

INVALID_REQUEST_ERROR

400, 404, 409

The request was malformed, missing parameters, or violated a business rule

AUTHENTICATION_ERROR

401, 403

Missing or invalid API key / JWT

RATE_LIMIT_ERROR

429

Too many requests

API_ERROR

500+

Something went wrong on our side


Error codes by endpoint

POST /tokens

Code
Status
When

customer_auth_invalid_wallet_address

400

Wallet address is not a valid EVM or Solana address

GET /markets/{ticker}

Code
Status
When

customer_market_not_found

404

No market with that ticker

GET /positions/{position_id}

Code
Status
When

customer_position_not_found

404

No position with that ID for this user

POST /quotes

Market eligibility:

Code
Status
When

quote_market_not_eligible

400

Market exists but isn't eligible for leverage

quote_market_not_ready

400

Market is not yet ready for trading

quote_event_not_started

400

Event has not started yet — trading opens at the scheduled start time

risk_engine_market_closed

400

Market is no longer accepting new positions

risk_engine_market_disabled

400

Market has been disabled (see params.reason)

risk_engine_market_settlement_detected

400

Market settlement has been detected

circuit_breaker_price_divergence_tripped

400

Price divergence circuit breaker has been triggered

quote_polymarket_market_closed

400

Polymarket market is closed

quote_polymarket_market_inactive

400

Polymarket market is inactive

quote_polymarket_market_not_accepting_orders

400

Polymarket market is not accepting orders

quote_polymarket_missing_token

400

Polymarket market is missing token configuration

quote_market_missing_polymarket_condition_id

400

Market is missing required Polymarket condition ID

quote_liquidation_not_viable

400

Liquidation price would be too low to maintain a position

Leverage validation:

Code
Status
When

quote_leverage_below_minimum

400

Leverage is below the minimum (2x)

quote_leverage_exceeds_maximum

400

Leverage exceeds the absolute maximum

quote_leverage_exceeds_model_max

400

Leverage exceeds the model's maximum for this market

quote_leverage_too_high_for_price

400

Leverage is too high relative to the current entry price

quote_price_too_low

400

Entry price is too low for a leveraged position

Market quality filters:

Code
Status
When

quote_entry_depth_too_low

400

Not enough order book depth

quote_entry_bid_depth_too_low

400

Minimum bid depth below threshold

quote_entry_capacity_exceeded

400

Notional exceeds market capacity

quote_entry_price_out_of_range

400

Current market price is outside tradeable range

quote_entry_spread_too_wide

400

Market spread exceeds maximum

quote_entry_order_book_stale

400

Order book data is stale

quote_entry_price_stale

400

Price data is stale

quote_entry_crypto_price_stale

400

Crypto price data is stale

quote_entry_sport_data_stale

400

Sport event data is stale

quote_entry_excluded_market_type

400

Market type is excluded from trading (see params.market_type)

quote_entry_excluded_sport

400

Sport type is excluded from trading (see params.sport)

quote_entry_exit_drop_too_high

400

Recent price drop exceeds safe entry threshold

quote_entry_market_too_elapsed

400

Market is too close to expiry

quote_entry_top_holder_too_high

400

Top holder concentration exceeds maximum

quote_entry_volume_too_low

400

24h trading volume is below minimum

quote_market_no_prices

400

No prices available for this market

quote_twap_data_unavailable

400

TWAP price data is unavailable for this market

quote_twap_data_stale

400

TWAP price data is stale

notional_selector_insufficient_liquidity

400

Not enough liquidity for the requested size

quote_side_capacity_exceeded

400

Notional exceeds available capacity on this side of the market

Position limits:

Code
Status
When

quote_user_position_limit_exceeded

400

User has reached their maximum number of open positions

quote_market_position_limit_exceeded

400

Market-level position limit reached

quote_side_position_limit_exceeded

400

Too many positions on one side of this market

quote_global_position_limit_exceeded

400

Platform-wide position limit reached

quote_partner_position_limit_exceeded

400

Partner's aggregate exposure cap reached

Other:

Code
Status
When

quote_hard_exit_too_close

400

Market is too close to resolution

quote_slippage_too_high

400

Slippage tolerance exceeds maximum allowed

quote_invalid_polymarket_wallet_address

400

Polymarket requires a valid EVM address


Errors with structured hints

Some error codes return additional machine-readable fields under error.params so you can act on them programmatically — for example, pre-filling an input with the maximum supported size instead of asking the user to retry until something fits. Don't regex-parse the message string — the values you need are typed under params.

params is only present on the codes documented below. Dispatch on code first, then read the keys you expect.

All pip values are decimal strings (10,000 pips = $1.00). bps values are numbers.

quote_side_capacity_exceeded

Key
Type
Description

available_capacity_usd_pips

string

Remaining notional headroom on this side of the market

min_notional_usd_pips

string

Minimum order size accepted by the protocol

max_supported_collateral_usd_pips

string

Maximum collateral the user can submit at their currently selected leverage and still fit. This is the value to surface in the UI — it maps directly to the user's collateral input

Example:

Treat the values as a snapshot — order book depth shifts continuously, so a user who waits before retrying may still hit the same error with a different max.

notional_selector_insufficient_liquidity

Key
Type
Description

slippage_max_usd_pips

string

Maximum notional that fits within the configured slippage budget

min_notional_usd_pips

string

Minimum order size accepted by the protocol

max_supported_collateral_usd_pips

string

Maximum collateral the user can submit at their currently selected leverage

Only present when the error is raised from the slippage path. The other call sites (e.g. an empty order book) omit params.

Position limit errors

The five *_position_limit_exceeded codes (quote_user_position_limit_exceeded, quote_market_position_limit_exceeded, quote_side_position_limit_exceeded, quote_global_position_limit_exceeded, quote_partner_position_limit_exceeded) all share the same shape:

Key
Type
Description

current_notional_usd_pips

string

The aggregate notional exposure that triggered the limit

limit_usd_pips

string

The configured limit at this scope

available_capacity_usd_pips

string

limit − current, clamped at 0

Leverage and slippage validation

Code

params keys

quote_leverage_below_minimum

current_leverage_bps, min_leverage_bps

quote_leverage_exceeds_maximum

current_leverage_bps, max_leverage_bps

quote_leverage_exceeds_model_max

current_leverage_bps, max_leverage_bps

quote_leverage_too_high_for_price

current_leverage_bps, entry_price_usd_pips, max_acceptable_leverage_bps, minimum_buffer_usd_pips

quote_slippage_too_high

current_slippage_bps, max_slippage_bps

quote_liquidation_not_viable

side, entry_price_usd_pips, liquidation_price_usd_pips, min_tolerance_pct_bps

Market disabled

Code

params keys

risk_engine_market_disabled

reason

Current reason values: force_disabled (admin killswitch).

Entry filter rejections

Code

params keys

quote_entry_depth_too_low

current_depth_usd_pips, min_depth_usd_pips

quote_entry_price_out_of_range

current_price_usd_pips, min_price_usd_pips, max_price_usd_pips

quote_entry_spread_too_wide

current_spread_usd_pips, max_spread_usd_pips

quote_entry_bid_depth_too_low

current_bid_depth_usd_pips, threshold_usd_pips

quote_entry_exit_drop_too_high

window, current_exit_drop, max_exit_drop

quote_entry_market_too_elapsed

pct_elapsed, max_pct_elapsed

quote_entry_top_holder_too_high

(none)

quote_entry_volume_too_low

current_volume_24h_usd_pips, min_volume_24h_usd_pips

quote_entry_excluded_market_type

market_type

quote_entry_excluded_sport

sport

quote_revision_required

When the requested parameters cannot be honored exactly but a revised quote would fit, this error returns the acceptable parameters so the client can re-quote (or set allow_revision=true upfront):

Key
Type
Description

revision

string

What was revised (leverage_reduced, notional_reduced, etc.)

requested_leverage_bps

number

The leverage the client asked for

requested_notional_usd_pips

string

The notional the client asked for

acceptable_leverage_bps

number

The leverage the protocol can honor

acceptable_notional_usd_pips

string

The notional the protocol can honor

acceptable_collateral_usdc_units

string

The collateral required at the acceptable parameters

Rate limiting (429)

All endpoints are subject to rate limiting. Throttled responses include a Retry-After header indicating how many seconds to wait before retrying. Use this value instead of a fixed backoff when available.

Internal server error (500)

A 500 response indicates an unexpected error on our side. These are always safe to retry with exponential backoff.


Handling errors in practice

Check the error type and code

Retry logic

Some errors are retryable, others aren't.

Retryable
Not retryable

internal_server_error

quote_market_not_eligible

too_many_requests

quote_leverage_below_minimum

request_already_in_progress

quote_user_position_limit_exceeded

risk_engine_market_closed

risk_engine_market_disabled

quote_entry_excluded_market_type

quote_entry_excluded_sport

quote_event_not_started

customer_auth_invalid_wallet_address

For retryable errors, use exponential backoff starting at 1 second.

SDK note: The SDK's HttpClient handles 429 retries (with Retry-After backoff) and 401 token refresh automatically, so you only need to handle business-logic errors in your application code.

Last updated