14.2.7
Concepts

Error handling

Errors are told apart by status code and a fixed error string. This page lists every error string and how to retry.

Shape

{"error":"invalid request"}

error is a fixed lowercase string you can compare directly. A few errors carry more fields: 429 too many credentials has live and max, 426 plugin_outdated has minimum and downloadUrl, 403 blocked has blockedUntil.

Responses that are not from the API

  • When the CDN (Cloudflare) refuses a request you get a 403 with an HTML body. A library default User-Agent such as Python-urllib triggers it. Put your implementation name in User-Agent and it passes. /api/v1/servers/* is exempt from this check.
  • A wrong method answers 405 and an unknown path 404. Their body is {"timestamp","status","error","path"}, where error is a sentence.
  • If Content-Type is not application/json or error is not in the list below, decide by the status code alone.

All errors

StatuserrorEndpointsMeaning
400invalid requestclaim, reportMissing required field, value out of range, string too long
400invalid seedmaps, jobsThe seed is not an integer in 1..2147483647
400invalid cursorseedscursor is not a valid seed
401invalid credentialreport, revokeNo key, wrong key, revoked key, or a report from an IP other than the registered one
401invalid codeplugin claimUnknown, expired, used or cancelled code
403no game serverservers/claimNo SCP:SL server answered at the request IP:port
403private addressservers/claimSent from a private or loopback address
403claim rejectedplugin claimRefused in manual review
403blockedmaps, jobsThe seed is blocked. Without blockedUntil the block is permanent
409address in useservers/claimA live registration exists at this IP:port and its key was not presented
426plugin_outdatedplugin claim, plugin reportpluginVersion is below the minimum
429rate limitedallA rate limit was exceeded
429too many credentialsservers/claimThis IP already holds the maximum number of live keys (live, max)
503db unavailableall blocking endpointsThe database is briefly unavailable
503disabledall blocking endpointsThe operator has switched this API off for now (feature names the switch). Keep retrying at the same backoff until it returns
503probe unavailableservers/claimThe server check failed on our side
503(varies)maps{"status":"busy","error":"…"}. The generation queue is full or generation failed

Retry rules

StatusRetryHow
400, 401, 409, 426NoFix the request, key or version and send a new request
403 no game server, private addressAfter fixing the causeThe issue interval is not spent, so resend as soon as it is fixed
403 claim rejectedNoClaim again with a new code
403 blockedAfter blockedUntilDo not retry when blockedUntil is absent
429YesAfter Retry-After seconds. Without reading it: start at 60 seconds, double each time, cap at 10 minutes
503YesStart at 5 seconds, double on every failure, cap at 5 minutes
Network error, timeoutYesSame as 503

429 responses carry a Retry-After header (seconds). Send again after that. The intervals above are for clients that do not read the header.

When a report gets 401

Stop reporting and tell the operator. The key was revoked or the server IP changed. A self-claim key is replaced by claiming the same IP:port again.

SLMAPS is the seed-map viewer for SCP: Secret Laboratory. These pages describe the public API of slmaps.com.slmaps.com ·