Error codes

Listings API HTTP status codes, the SYxxxxx error codes, and the two error-envelope shapes the v4 API returns.

The Listings API uses conventional HTTP status codes to report the outcome of a request. Error codes are SY-prefixed and travel inside the error message string, formatted as SYxxxxx: <human-readable reason>.

HTTP status codes

HTTP status code summary

StatusMeaningTypical SY codePython SDK exception
200 OKRequest succeeded. For writes, also check the mutation body (see below).--
400 Bad RequestMalformed request, an unparseable filter, an invalid enum value, or a malformed ID.SY90006, SY90001ValidationError
401 UnauthorizedThe API key is missing, malformed, or revoked.SY90005AuthenticationError
403 ForbiddenThe key is valid but not permitted to access the resource.SY90003PermissionDeniedError
404 Not FoundThe path, or a resource addressed by ID, does not exist.SY90002NotFoundError
422 Unprocessable EntityThe request was well-formed, but a value could not be processed (for example, an unknown or ambiguous category).-ValidationError
429 Too Many RequestsYou exceeded your plan's rate limit. Honor the Retry-After header.-RateLimitError
5xxA server-side or upstream error. Safe to retry with backoff.SY90007InternalServerError

Two envelope shapes

Every failure carries an errors array. Where that array lives depends on whether the request failed before or after it reached the resolver.

1. Request-level: top-level errors[]

Authentication, authorization, and malformed-request failures short-circuit before the operation runs. They return the matching 4xx status (above) with the error at the top level of the response.

JSON
{  "data": { "createLocation": null },  "errors": [{ "message": "SY90005: Invalid Token" }]}

2. Mutation validation: nested data.<operation>.errors[]

A create, update, or publish request that is otherwise well-formed reaches the resolver, so the transport succeeds with HTTP 200. If the resolver rejects the input on a business rule, the mutation reports the failure nested under the operation's own payload in data.<operation>.errors. On success this array is present and empty ("errors": []).

JSON
{  "data": {    "createLocation": {      "errors": [        { "message": "SY10126: City is Mandatory" },        { "message": "SY10010: state_iso" }      ],      "location": null    }  }}

Always read data.<operation>.errors on a write, even on a 200 with a populated data.<operation> object: a mutation can partially fail and report it here.

Common codes

Common SY error codes

CodeMessageHTTP statusMeaning
SY90005Invalid Token401The API key is missing, malformed, or revoked. Re-issue a key from the dashboard and send it as Authorization: API <your-key>.
SY90001Not authorized to access this resource401 / 403The key was rejected for the requested resource. The Python SDK raises this as AuthenticationError.
SY90002Invalid Id404 / 400A path or argument ID could not be resolved (often a bad or non-base64 relay ID).
SY10126City is Mandatory200 (mutation body)A required field (city) was omitted from the input.
SY10010state_iso200 (mutation body)The stateIso value is missing or invalid. See the countries and states endpoint for valid values.

Validation codes in the SY10xxx range correspond to a specific input field; the message names the field or the rule that failed. Auth and authorization codes in the SY90xxx range are request-level and arrive at the top level with the matching status.

Connected-account codes

Codes in the SY810xx range come from the Connected Accounts endpoints that import or link a publisher listing. They arrive nested in the mutation body on an HTTP 200 (envelope shape 2 above), so read data.<operation>.errors even when the status is a success.

SY810xx connected-account and import codes

CodeMeaningWhat to do
SY81019No user could be resolved for the account behind the key.Contact support: the account has no active primary user.
SY81066The connectedAccountId does not exist, or the account is archived.Re-read the ID from GET /connected-accounts.
SY81067The connectedAccountListingId could not be decoded or resolved.Re-fetch it from the id of a connected-account-listings record.
SY81068That listing is already linked to a location.Disconnect it first, or pick another listing.
SY81069The connected account's credentials are no longer valid.Reconnect the account via connect-google or connect-facebook.
SY81070The listing does not belong to the connected account you named.Pair each listing with the account it came from. A common cause is fetching listings without connectedAccountId in the body, which returns another account's listings.
SY81071An unexpected error occurred while creating the location.Retry; if it persists, contact support.
SY81072Location creation failed while building or saving.Retry; if it persists, contact support.
SY81073The listing type is not supported for import.Only Google and Facebook listings can be imported.
SY81074Google returned no data for the listing.Confirm the listing still exists and the account still manages it.
SY81075Google's API rate limit was exceeded.Retry later with backoff.
SY81076Fetching the listing from Google failed.Retry; check the account's Google permissions.
SY81077The country could not be determined from the Facebook page.Add a country to the page's address on Facebook, then retry.
SY81078Building location data from the Facebook page failed.Retry; if it persists, contact support.
SY81081The listing has no primary category set.Set a primary category on the listing, then retry.
SY81082The listing's country is not supported.See the countries and states endpoint for supported countries.
SY81083No category mapping exists for the listing's primary category in that country.Category mappings are country-specific. Change the listing's primary category to a supported one, or contact support to have the mapping added.
SY81084The Facebook publisher record is missing.Contact support.
SY81085No category mapping exists for the Facebook category.Change the page's category, or contact support.
SY81086Location creation was rejected by a business rule. The nested message carries the underlying code, for example SY10151 when the account is out of location seats.Read the nested message; for SY10151, add a location add-on or upgrade the plan.
SY81087The location-creation request failed at the GraphQL layer.Retry; if it persists, contact support with the timestamp.
SY81088Location creation failed for an unrecognised reason.Contact support with the timestamp.
SY81089An internal service call returned a non-success status. Not a problem with your request.Retry once; if it persists, contact support with the timestamp so we can trace the internal call.
SY81090An unexpected error occurred during the internal location-creation call.Retry; if it persists, contact support with the timestamp.

rate_limited

429 Too Many Requests: the account exceeded its plan's rate limit. The body is the standard error envelope carrying a retry_after_seconds hint, a correlation_id to quote in support requests, and a doc_url that links back to this section:

JSON
{  "error": {    "code": "RATE_LIMITED",    "message": "Too many requests. Slow down.",    "retry_after_seconds": 30,    "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c",    "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited"  }}

Wait for retry_after_seconds (or the Retry-After header when present), then retry with exponential backoff. See Rate limits for the per-plan limits and a reference backoff implementation.

Dev-portal control-plane errors

Account and key-management endpoints in the developer portal (the dashboard's own API routes) return a single, structured error envelope: distinct from the REST errors[] shapes above. Each code carries a correlation_id and a doc_url that links back to the matching section here.

JSON
{  "error": {    "code": "AUTH_INVALID_KEY",    "message": "Session is invalid or expired.",    "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c",    "doc_url": "https://listingsapi.com/docs/error-codes#auth_invalid_key"  }}

auth_missing_key

401: No credential was provided. Sign in again, or send your key as Authorization: API <your-key>.

auth_invalid_key

401: The session or key is invalid or expired. Re-authenticate or re-issue a key from the dashboard.

auth_insufficient_scope

403: The credential is valid but not permitted for this action. A read-scoped key cannot call write endpoints; issue a write key if you need one.

not_found

404: The requested resource, or a resource addressed by ID, does not exist.

conflict

409: The request conflicts with the current state of the resource (for example, revoking a key that is already revoked).

validation_failed

422: The request body failed validation. The envelope's field and details name the offending input.

internal_error

500: An unexpected server-side error. Safe to retry with exponential backoff; quote the correlation_id if you contact support.

dependency_unavailable

503: A required upstream dependency is temporarily unavailable. Retry with backoff.

For 429, see rate_limited above.

Handling errors in code

Check the HTTP status first; then, for writes, scan the mutation body for a nested errors array:

Python
resp = client._request(method="POST", path="/api/v4/locations", body=payload) # `_request` raises on a non-2xx status (AuthenticationError, ValidationError,# and so on). On a 200, a mutation can still report field errors in its payload:op = (resp.get("data") or {}).get("createLocation") or {}if op.get("errors"):    messages = [e["message"] for e in op["errors"]]    raise RuntimeError(f"Listings API error: {messages}")

The Python SDK does both for you: it maps each HTTP status to a typed exception and also raises on error payloads returned inside a 200 body.