Error codes

Listings API HTTP status codes, the SYxxxxx error codes for Listings and Social, and the three error response 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 response 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
402 Payment RequiredThe account has an unpaid invoice, so API access is paused. A Social-only unpaid invoice pauses only the Social endpoints. See payment_required and social_payment_required.-APIError
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 error. Safe to retry with backoff on a read; see the write caveat below before repeating a write.SY90007InternalServerError

Three response shapes

Most failures carry an errors array, either at the top level or nested inside the operation's result, as the sections below show. A few failures return a single error object instead: rate limiting (429) and some request-level failures (400/500 with a code such as INTERNAL_SERVER_ERROR). Test for both: errors is an array, error is an object.

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. Write validation: nested data.<operation>.errors[]

A create, update, or publish request that is otherwise well-formed returns HTTP 200. If the input breaks a business rule, the failure is reported 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    }  }}

3. Gateway-level: a single top-level error object

Rate limiting and unexpected gateway faults short-circuit before translation and return one error object with a code, a message, and a correlation_id. See rate_limited below for the 429 body.

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

A 402 Payment Required response has no error wrapper: code, message, doc_url and, when there is an invoice to pay, pay_url are at the top level. See payment_required below.

Retrying a write is not free

The v4 API has no Idempotency-Key support: the header is ignored, and no endpoint detects repeated writes. A create, update, or publish call that times out or returns a 5xx may still have committed on the server, so a blind retry can produce a duplicate location, post, or review reply.

Retry reads freely with backoff. For a write, read back first: look the record up by a key you control (storeId, a store code, the interaction's response list) and only repeat the call if it is genuinely absent.

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 this resource. Both the Python and Node SDKs raise it as AuthenticationError.
SY90002Invalid Id404 / 400A path or argument ID could not be resolved (often a bad or non-base64 relay ID).
SY10126City is Mandatory200 (response body)A required field (city) was omitted from the input.
SY10010state_iso200 (response 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 response body on an HTTP 200 (response 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.
SY81083The Google listing could not be imported.Contact support with the timestamp.
SY81084An internal error occurred while preparing the Facebook import.Retry; if it persists, contact support with the timestamp.
SY81085The Facebook page could not be imported.Contact support with the timestamp.
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.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.

Social codes

Codes in the SY950xx range come from the Social endpoints: brands, connections and social posts. Like the connected-account codes, they arrive nested in the response body on an HTTP 200, so read data.<operation>.error (and data.<operation>.errors on the bulk routes) even when the status is a success.

SY950xx Social codes

CodeMeaningWhat to do
SY95041The account is at its brand limit. Not reachable on an API plan: brands are unlimited there.Nothing to do on an API plan. If you ever see it, report it: GET /social/limits should be returning brands: null.
SY95042The account is at its connection limit for the current billing period.The cap is compared against usage.connections from GET /social/limits — the billable count: connected now plus released this period. A slot freed by disconnecting or by archiving a brand is held until the period ends, so a recent disconnect does not clear this error. Relink one of the accounts you released to the brand it was on (free, it reuses that slot), buy another 5-connection pack (immediate), or wait for renewal, when usage.connectionsReleased slots return. Attaching a released account to a different brand does not reuse the slot. See Plans and add-ons.
SY95043No brand with that ID on this account, or the brand is archived.Re-read the ID from GET /social/brands. Brand IDs are plain UUIDs, not Base64 relay IDs.
SY95044That platform is not enabled for this account.The account's Social plan does not cover the platform you asked to connect. Contact support or pick a platform the account has.
SY95045The brand has no connected channel for that platform.Send the user through a connection link for that platform, or drop it from platforms. Also seen when the channel was disconnected after the post was scheduled.
SY95046The schedule or timezone is invalid.Send scheduledAt or scheduleDate + scheduleTime, never both. scheduledAt needs a UTC offset; scheduleTime is HH:MM. Timezones are IANA identifiers (tzCode).
SY95047No bulk job with that ID on this account.Re-read job.id from the bulk create response. Jobs are not retained forever.
SY95048The bulk request exceeds the row limit.Send at most 500 rows per request and split the rest into further batches. Nothing was created.
SY95049The redirect URL is invalid.redirectUrl and errorUrl on a connection link must be absolute https URLs you control.
SY95050Bulk validation failed; see the per-row errors.Nothing was created. Read job.results[]: each rejected row carries its 0-based index, its clientReference, and the reason in errors[]. Fix those rows and resend the whole batch.
SY95051The brand has not met the 90-day tenure requirement.A brand cannot be archived until it is 90 days old. The response also reports status: "TENURE_NOT_MET" and nothing changed. Retry after the 90th day, when the brand and its connections are archived immediately — though their connection slots are held until the end of the billing period. See the tenure rule.
SY95052The connected channel does not belong to this brand.Pair each connection with the brand it was created on. Common when an insights call is built from one brand's post and another brand's channel ID.

SY95042 and SY95044 are entitlement failures, not input errors: retrying without changing the plan will fail identically. SY95045, SY95046, SY95049 and SY95052 are input errors, fixable in the next request.

Listings entitlement codes

Listings plan codes

CodeMeaningWhat to do
SY10150The account is at its location limit.Archive a location, buy an extra-location add-on, or upgrade. See Plans and add-ons.
SY10151The account is out of location seats on this plan. On a sandbox day pass, both of its locations are in use.Same remedies as SY10150. On a day pass, update an existing location or choose a paid plan. Also surfaces nested inside SY81086 when a location is created from a connected-account listing.
SY10152The location has not been active long enough to be archived.Locations must be active for the account's minimum tenure, 90 days by default, before POST /locations/archive accepts them. Wait out the tenure.
SY10155The account has no Listings plan, so locations cannot be created.The API key belongs to an account with no Listings subscription, such as a Social-only account. Locations are part of the Listings product; subscribe to it before calling POST /locations.

rate_limited

429 Too Many Requests: the account exceeded its plan's rate limit. The body is the standard error response 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.

payment_required

402: The last payment for this account did not go through, so every /api/v4 endpoint is paused. The body includes pay_url, the Stripe page for the unpaid invoice, when one is available, and the X-Error-Code response header carries the same code. You can still open the Billing page in the dashboard to pay.

JSON
{  "code": "payment_required",  "message": "This account has an unpaid invoice, so API access is paused. Pay the invoice to restore access.",  "pay_url": "https://invoice.stripe.com/i/acct_123/test_abc",  "doc_url": "https://listingsapi.com/docs/error-codes#payment_required"}

Access comes back within a minute after the last open invoice is paid. If the invoice is still unpaid 3 days after the first failed payment, the Listings subscription is cancelled and the account's locations are archived. If the account also has an active Social subscription, it keeps Social access; otherwise the account is closed and its API keys stop working.

social_payment_required

402: The last payment for the Social subscription did not go through, so the Social endpoints (/api/v4/social/*) are paused. Listings endpoints keep working. The body has the same fields as payment_required, with "code": "social_payment_required". If the invoice is still unpaid 3 days after the first failed payment, the Social subscription is cancelled and the account's brands are archived. An account with no Listings subscription is closed, and its API keys stop working.

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 response: 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 response's field and details name the offending input.

internal_error

500: An unexpected server-side error. Retry a read with exponential backoff; for a write, read the record back first (see Retrying a write is not free). Quote the correlation_id if you contact support.

dependency_unavailable

503: A service the API depends on 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 response body for a nested errors array:

Python
from listingsapi import APIError, ListingsAPI client = ListingsAPI(api_key=os.environ["LISTINGSAPI_KEY"]) try:    location = client.locations.create(input=payload)except APIError as e:    # Raised for a non-2xx status (AuthenticationError, ValidationError, and    # so on) and for an error payload returned inside a 200 body.    raise RuntimeError(f"Listings API error: {e}") from e

Against the raw HTTP API the same two checks are explicit, the status code and then the response payload:

Python
resp = requests.post(    "https://listingsapi.com/api/v4/locations",    headers={"Authorization": f"API {os.environ['LISTINGSAPI_KEY']}"},    json=payload,    timeout=30,)resp.raise_for_status()body = resp.json() op = (body.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.