LP integration — Errors, idempotency & rate limits¶
Error envelope¶
Errors are JSON { "error": "<machine_code>", "detail"?: "<human string, often ≤200 chars>" }
with the HTTP status carrying the category. The FE wrapper throws on any non-2xx
and surfaces oracle <status> <path>: <body slice>.
| Code | HTTP | Where |
|---|---|---|
invalid_json |
400 | any POST with unparseable body |
invalid_shape |
400 | register, withdraw, lp-bot/start |
invalid_order_shape |
400 | POST /v1/orders (order schema floor) |
invalid_pubkey |
400 | progress, lp-bot/* |
invalid_address |
400 | robinhood-address (malformed EVM 0x address) |
stale_timestamp |
400 | register (timestamp >60s skew) |
invalid_amount |
400 | withdraw (non-positive / unparseable) |
invalid_signature_format |
400 | sig not 64 bytes |
scope_missing / scope_forbidden |
400 | lp-bot delegate/session |
expiry_out_of_range |
400 | lp-bot delegate |
invalid_signature |
403 | register, withdraw, lp-bot delegate |
session_user_mismatch |
403 | withdraw (session ≠ body user) |
trading_disabled |
403 | POST /v1/orders (gate) |
lp_disabled |
403 | /v1/lp-bot/* (gate) |
session_revoked / session_expired / user_mismatch |
403 | lp-bot start |
not_found |
404 | markets/{id} |
session_not_delegated |
404 | lp-bot start |
session_already_delegated |
409 | lp-bot delegate (session_pub reuse) |
nonce_stale |
422 | lp-bot delegate |
engine_rejected |
422 | withdraw (balance/nonce fail; detail from the matching service) |
rate_limited |
429 | rate limiter (retry_after seconds) |
db_error |
500 | lp-bot delegate |
derivation_failed |
500 | robinhood-address |
engine_unreachable |
502 | withdraw (the API could not reach the matching service) |
engine_binding_disabled |
503 | withdraw (upstream matching service unavailable) |
registration_failed |
503 | robinhood-address (address could not be registered for deposit watching — retry) |
Idempotency¶
- robinhood-address — idempotent; repeated calls return the same derived address.
- builders/register — idempotent; re-registering returns the same
api_key. - lp-bot/start — idempotent-replace; a new start auto-stops the prior active bot rather than erroring.
- lp-bot/delegate — not replayable; nonce must strictly increase; a reused
session_pubreturns409. - withdraw-signed — governed by the per-user nonce; reuse is rejected by the matching service. Do not retry a withdraw with the same nonce — choose a new (greater) nonce on retry.
Rate limits¶
| Bucket | Limit | Applies to |
|---|---|---|
| Per-wallet order placement | 50 / 60s | POST /v1/orders (keyed on session user) |
| Per-IP | 600 / 60s (≈10/s) | /v1/orders/*, /v1/withdraw-signed |
| Per-IP | 60 / 60s | /v1/events (writes) + administrative endpoints |
Deposit service robinhood-address |
30 / 60s (per-IP) | GET /v1/deposit/robinhood-address/{user} |
Exceeding a bucket returns 429 { "error": "rate_limited", "retry_after": <secs> }.
Trading pauses¶
Trading may be temporarily paused. When paused, POST /v1/withdraw-signed is
blocked before any other check.