Read both HTTP status and error.code.
Error Envelope
Errors use one structured JSON shape across the runtime API.
Clients should not parse English text to infer behavior. Persistly returns a stable error envelope with a machine-readable code and optional structured details.
Response
HTTP 413 Payload Too Large
The same envelope shape is used for 400, 401, 404, 429, and 500 responses.
HTTP/1.1 413 Payload Too Large
Content-Type: application/json
{
"error": {
"code": "payload_too_large",
"message": "State exceeds the maximum allowed size.",
"details": {
"field": "state",
"maxBytes": 262144
}
}
}Rate Limit
HTTP 429 includes retry guidance.
SDKs should surface this as a typed rate-limit error so games can pause sync attempts instead of hammering the runtime.
HTTP/1.1 429 Too Many Requests
Retry-After: 18
Content-Type: application/json
{
"error": {
"code": "rate_limited",
"message": "Too many runtime requests for this environment.",
"details": {
"retryAfter": 18,
"windowSeconds": 60
}
}
}Handling Rules
Use the envelope to drive client behavior.
Treat 400 and 413 as caller/actionable problems.
Treat 401 as key/environment/auth configuration failure.
Treat 429 as retry-later behavior. Honor Retry-After before retrying.
Treat 500 as unknown-result behavior and retry intentionally.
Rate Limits
Plan limits protect the runtime without changing the save contract.
Per-minute limits come from the project's active plan entitlement.
The runtime uses a 60-second window for request-rate enforcement.
Do not retry every frame. Back off until Retry-After has elapsed.
Monthly request totals are plan boundaries today; hard monthly enforcement needs usage aggregation first.