Errors, retries & limits
The error envelope, every code the machine rails return, rate limits, and what is safe to retry.
On this page
The envelope#
Every error on /partner/v1/… is JSON with a stable machine-readable code. Branch on code; the message is for your logs and may change.
{
"error": {
"code": "pool_too_low",
"message": "this order costs 6930 cents and the payouts pool holds 5000",
"retryable": false
}
}retryable is our advice: true means the same request may succeed later without changes (an outage, a rate limit, a paused feature). Idempotency errors add an operationState field describing what became of the original attempt.
Error codes#
Authentication and shape
| Status | Code | When |
|---|---|---|
| 401 | partner_key_invalid | Missing, unknown or revoked API key. |
| 403 | partner_account_inactive | Your company is suspended. |
| 400 | invalid_request | A body or filter the route could not use, with the reason in the message. |
| 400 | unsupported_game | A game other than the ones we support. |
| 409 | idempotency_key_conflict | The key was already used with a different payload. |
| 409 | idempotency_in_progress | The original request with this key is still running. |
| 422 | idempotency_key_required | A mutating route was called without the header. |
| 429 | rate_limit_exceeded | Too many requests for this company on this route. Wait for Retry-After and retry. On a read route the body is a plain {"detail": "too many requests"} rather than the envelope; the status and header are the same. |
Customers
| Status | Code | When |
|---|---|---|
| 404 | customer_not_found | No customer of yours matches the reference. Also the answer for someone linked to another partner. |
| 404 | roblox_account_not_found | Roblox does not know that username. |
| 409 | external_ref_in_use | That externalRef already names a different customer of yours. |
| 409 | customer_not_ready | The customer is linked but has no MM2Empire account yet, so there is nothing to quote, sell or deliver to. It is created the first time they deposit. |
MM2 Payments
| Status | Code | When |
|---|---|---|
| 409 | payments_disabled | Buying is switched off in the console. |
| 409 | item_not_accepted | You (or MM2Empire, on our funding) do not buy this item, or the price falls below your minimum payout. |
| 409 | stock_limit_reached | You already hold the maximum number of copies you set for this item. |
| 409 | pool_too_low | Your Payments pool cannot cover the payout. |
| 409 | item_unavailable | The copy is listed, in a trade, being withdrawn or on hold and cannot move right now. |
| 404 | record_not_found | No payment of yours has that id. |
| 404 | session_not_found | No pop-up session of yours has that id. |
| 429 | pricing_mode_cooldown · funding_source_cooldown · claim_cooldown | A setting was changed, or earnings claimed, less than 15 minutes ago. Retry-After says when it reopens. |
MM2 Payouts
| Status | Code | When |
|---|---|---|
| 409 | payouts_disabled | Selling is switched off in the console. |
| 409 | pool_too_low | Your Payouts float cannot cover the order. |
| 400 | order_too_large | More than 4 item types or 100 items, or over the per-order ceiling or daily cap you set. |
| 409 | nothing_purchased | None of the stacks were still available at the quoted prices. |
| 409 | pool_is_shared | You tried to fund or release the Payouts float while it shares the Payments pool. |
| 404 | order_not_found | No order of yours has that id. |
| 503 | withdrawals_disabled | Item delivery is paused platform-wide during an incident. Retryable. |
Rate limits#
Limits are per company per route family, over a rolling minute, and shared across all of your API keys. A refused request returns 429 with a Retry-After header in seconds; inside a write carrying an Idempotency-Key the body is the error envelope with code rate_limit_exceeded, and on a read it is {"detail": "too many requests"}. The figures below are the current limits; they are generous for a real integration and tight enough that a runaway loop stops quickly.
| Route family | Requests per minute |
|---|---|
| Reads: customers, sessions, payments, orders, withdrawals, listings, claims | 120 |
| Link a customer · open or close a session · inventory · quote · rate card · deposits · pool | 60 |
| Payout orders | 30 |
| Sell · withdrawals | 20 |
What to retry#
- Network timeouts and 5xx: retry with the same
Idempotency-Key. That is what the header is for. - 429: wait for
Retry-After, then retry with the same key. - 409 with `retryable: true` (for example
withdrawals_disabled): the request is fine and the platform is not ready; back off for a minute. - Any other 4xx: do not retry unchanged. The request will be refused the same way every time.