Skip to content

Errors & rate limits

Every operation spends from the bucket of its key or token (300 requests per minute) and the account’s bucket (600 requests per minute). Heavy calls - statistics, widget diagnostics, form responses, contact activity, contact search and segment filters, broadcast recipients, automation runs, tag deletion, integration lists and delivery records, e-mail domain verification, event subscription previews, tests and delivery journals - also spend from a heavy bucket (60 requests per minute); creating or restoring contacts, and running an automation for a contact by e-mail, from a creation bucket (60 requests per minute). Failed authentication is limited per client address (30 requests per minute); once spent, every request from that address is refused until the window ends.

X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset describe the tightest bucket spent by the call. An exhausted bucket is 429 rate_limited with Retry-After in seconds. When limits cannot be enforced the call is refused with 503 temporarily_unavailable; retry later.

Errors are RFC 7807 application/problem+json. type, title, status, instance and request_id are always present. reason is the stable code to branch on; next says in one sentence what to do next. detail is a human-readable text and may be null. errors lists the invalid fields of a 422 validation_failed: loc is stable, while its type and msg are texts for people and may change. metadata carries the ids involved, for some reasons only.

type is https://api.getsitecontrol.com/errors/<reason>: an identifier, no page opens at that address.

reasonstatustitlenext
unauthenticated401UnauthenticatedSend an API key or an access token as Authorization: Bearer.
invalid_token401Invalid API key or access tokenThe key or token is revoked or no longer valid; use an active API key, or connect the app again for a new token.
forbidden403ForbiddenThe key or user lacks the access this call needs, named in metadata.permission; ask the account owner or an admin to grant it instead of retrying.
account_suspended403Account suspendedThe account or the site is suspended and the API cannot change that; tell the account owner instead of retrying.
not_found404Not foundCheck the path and the method against the API reference.
validation_failed422Validation failedFix the fields named in errors and send the request again.
invalid_cursor422Invalid cursorPass next_cursor exactly as returned, with the parameters it was issued for, or start again without cursor.
stats_period_too_long422Statistics period too longSplit the period into parts no longer than the detail allows and call once per part.
idempotency_in_progress409Idempotency key in progressThe first request with this Idempotency-Key is still running; repeat the same request later to get its result.
idempotency_key_reused422Idempotency key reusedSend a new Idempotency-Key; reuse a key only to repeat the same request with the same body and version.
feature_unavailable403Feature unavailableThe plan lacks the feature in metadata.feature; tell the account owner instead of retrying.
unsupported_version400Unsupported versionSend one of the versions named in the detail in GSC-Version, or omit the header for the latest.
payload_too_large413Payload too largeSend a smaller body; the detail gives the limit in bytes.
rate_limited429Rate limitedWait Retry-After seconds, then repeat the request.
temporarily_unavailable503Temporarily unavailableThe detail names the part that is unavailable; retry the request later, with narrower filters or a shorter period if it timed out.
internal500Internal errorRetry once later; if it fails again, report the request_id to Getsitecontrol support.
site_not_found404Site not foundUse a site_id from list_sites.
folder_not_found404Folder not foundUse a folder id from list_folders with the same type, or 0 for General.
widget_not_found404Widget not foundUse a widget id of this site from list_widgets.
response_not_found404Response not foundUse a response id from list_responses; a response still being completed shows up shortly, so retry once.
ab_test_not_found404A/B test not foundUse a test id from list_widget_ab_tests; a stopped test is gone.
ab_test_winner_not_found404Winner is not in the testPass the id of one of the test’s widgets as winner_id, or omit it to keep the leader.
ab_test_single_widget409The test has one widgetStop needs two or more widgets; take the widget out with remove_widget_ab_test instead.
tag_not_found404Tag not foundUse a tag id from list_tags.
field_not_found404Field not foundUse a field id from list_contact_fields.
contact_not_found404Contact not foundUse a contact id from list_contacts.
segment_not_found404Segment not foundUse a segment id from list_segments.
tag_name_taken409Tag name takenUse the existing tag (find it by name in list_tags) or pick another name.
field_name_taken409Field name takenUse the existing field (find it by name in list_contact_fields) or pick another name.
field_name_invalid422Field name invalidPick a name with at least three latin letters or digits and short enough; the detail says which rule failed.
contact_email_taken409Contact email takenThe address belongs to the contact in metadata.contact_id: update that contact instead. Without an id another request took it at the same moment: repeat the call.
contact_status_transition422Contact status transition not allowedSend a status allowed from metadata.status (see update_contacts), or leave status out; a bounced contact changes it only with a new e-mail.
contact_field_invalid422Contact field invalidFix metadata.field_id: use field ids from list_contact_fields with values of their type; tags go in add_tags by name.
contact_tag_invalid422Contact tag invalidFix the tag name in metadata.tag as metadata.problem says.
contact_value_invalid422Contact value invalidFix the value metadata.field names as metadata.problem says.
contact_unreadable422Contact cannot be readThe stored contact cannot be read or changed; only delete_contacts works on it.
segment_conditions_invalid422Segment conditions invalidFix the conditions as metadata.problem says; the saved conditions of a segment are replaced with update_segment.
segment_in_use409Segment in useRemove the segment from the automations, broadcasts and segments listed in metadata first (segments with update_segment), then delete it.
broadcast_not_found404Broadcast not foundUse a broadcast id from list_broadcasts.
email_not_found404Email not foundUse an e-mail id from get_broadcast or get_automation; a new email exists here once its draft is saved.
email_domain_not_found404Email domain not foundUse a domain id from list_email_domains.
email_sending_disabled409Email sending disabledE-mail sending is off for the site and the API cannot turn it on; call diagnose_email_sending for the cause and who can fix it.
email_balance_exhausted402Email balance exhaustedTell the account owner to top up the e-mail balance, then repeat the call.
email_draft_not_found404No draft of this emailThere is nothing to revert, discard or list: you never changed this email, or your draft was discarded or dropped after 30 days unchanged.
email_changed_since_draft409The email was saved after your draft startedTell the user who saved the email and when (metadata.saved_by, metadata.saved_at); save with overwrite: true only if they agree to replace that save, or discard the draft and redo the change.
email_draft_revision_not_found404The draft does not keep that revisionPick a to_revision from the draft’s history, or go back at most metadata.revision - 1 steps, and never more than 20.
email_preview_unavailable503No live preview linkShow the user pictures of the email instead.
automation_not_found404Automation not foundUse an automation id from list_automations.
automation_inactive409Automation inactiveTurn the automation on with enable_automation, then run it again.
automation_not_startable409Automation not startable by APIOnly an automation with the manual or webhook trigger can be run; pick one in list_automations.
automation_invalid422Automation invalidThe automation needs a valid trigger, which is set in the admin; enable it after that.
run_in_progress409Run in progressThe contact is already in this automation (metadata.state); start it again only after that run ends.
integration_not_found404Integration not foundUse an integration id from list_integrations.
delivery_not_found404Delivery not foundUse a delivery id from list_integration_deliveries or list_event_subscription_deliveries of the same integration or event subscription.
event_subscription_not_found404Event subscription not foundUse an event subscription id from list_event_subscriptions.
event_subscription_limit_reached409Event subscription limit reachedDelete an event subscription with delete_event_subscription, or add the events to an existing one with update_event_subscription.
delivery_not_redeliverable409Delivery cannot be redeliveredThe detail says why: wait for a pending delivery to finish, call test_event_subscription again for a test, or switch the event subscription on with update_event_subscription; otherwise it cannot be redelivered.
image_too_large413File too largeSend a file of at most 3 MB.
image_type_not_allowed422File type not allowedSend an image file.
image_unsafe_svg422Unsafe SVGRemove scripts and external links from the SVG, or send a PNG.
image_url_unreachable422File could not be downloadedSend a public http or https URL, or the file itself in data.
image_unreadable422Not an imageSend an image file or its public URL.
image_upload_link_invalid404Upload link expiredGet a fresh link from create_image_upload_link.
image_source_required422File source requiredGive exactly one of url and data, and name with data.

Source: OpenAPI specification. Paths that start with /v1 are on https://api.getsitecontrol.com.