Errors & rate limits
Rate limits
Section titled “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
Section titled “Errors”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.
| reason | status | title | next |
|---|---|---|---|
unauthenticated | 401 | Unauthenticated | Send an API key or an access token as Authorization: Bearer. |
invalid_token | 401 | Invalid API key or access token | The key or token is revoked or no longer valid; use an active API key, or connect the app again for a new token. |
forbidden | 403 | Forbidden | The 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_suspended | 403 | Account suspended | The account or the site is suspended and the API cannot change that; tell the account owner instead of retrying. |
not_found | 404 | Not found | Check the path and the method against the API reference. |
validation_failed | 422 | Validation failed | Fix the fields named in errors and send the request again. |
invalid_cursor | 422 | Invalid cursor | Pass next_cursor exactly as returned, with the parameters it was issued for, or start again without cursor. |
stats_period_too_long | 422 | Statistics period too long | Split the period into parts no longer than the detail allows and call once per part. |
idempotency_in_progress | 409 | Idempotency key in progress | The first request with this Idempotency-Key is still running; repeat the same request later to get its result. |
idempotency_key_reused | 422 | Idempotency key reused | Send a new Idempotency-Key; reuse a key only to repeat the same request with the same body and version. |
feature_unavailable | 403 | Feature unavailable | The plan lacks the feature in metadata.feature; tell the account owner instead of retrying. |
unsupported_version | 400 | Unsupported version | Send one of the versions named in the detail in GSC-Version, or omit the header for the latest. |
payload_too_large | 413 | Payload too large | Send a smaller body; the detail gives the limit in bytes. |
rate_limited | 429 | Rate limited | Wait Retry-After seconds, then repeat the request. |
temporarily_unavailable | 503 | Temporarily unavailable | The detail names the part that is unavailable; retry the request later, with narrower filters or a shorter period if it timed out. |
internal | 500 | Internal error | Retry once later; if it fails again, report the request_id to Getsitecontrol support. |
site_not_found | 404 | Site not found | Use a site_id from list_sites. |
folder_not_found | 404 | Folder not found | Use a folder id from list_folders with the same type, or 0 for General. |
widget_not_found | 404 | Widget not found | Use a widget id of this site from list_widgets. |
response_not_found | 404 | Response not found | Use a response id from list_responses; a response still being completed shows up shortly, so retry once. |
ab_test_not_found | 404 | A/B test not found | Use a test id from list_widget_ab_tests; a stopped test is gone. |
ab_test_winner_not_found | 404 | Winner is not in the test | Pass the id of one of the test’s widgets as winner_id, or omit it to keep the leader. |
ab_test_single_widget | 409 | The test has one widget | Stop needs two or more widgets; take the widget out with remove_widget_ab_test instead. |
tag_not_found | 404 | Tag not found | Use a tag id from list_tags. |
field_not_found | 404 | Field not found | Use a field id from list_contact_fields. |
contact_not_found | 404 | Contact not found | Use a contact id from list_contacts. |
segment_not_found | 404 | Segment not found | Use a segment id from list_segments. |
tag_name_taken | 409 | Tag name taken | Use the existing tag (find it by name in list_tags) or pick another name. |
field_name_taken | 409 | Field name taken | Use the existing field (find it by name in list_contact_fields) or pick another name. |
field_name_invalid | 422 | Field name invalid | Pick a name with at least three latin letters or digits and short enough; the detail says which rule failed. |
contact_email_taken | 409 | Contact email taken | The 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_transition | 422 | Contact status transition not allowed | Send 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_invalid | 422 | Contact field invalid | Fix metadata.field_id: use field ids from list_contact_fields with values of their type; tags go in add_tags by name. |
contact_tag_invalid | 422 | Contact tag invalid | Fix the tag name in metadata.tag as metadata.problem says. |
contact_value_invalid | 422 | Contact value invalid | Fix the value metadata.field names as metadata.problem says. |
contact_unreadable | 422 | Contact cannot be read | The stored contact cannot be read or changed; only delete_contacts works on it. |
segment_conditions_invalid | 422 | Segment conditions invalid | Fix the conditions as metadata.problem says; the saved conditions of a segment are replaced with update_segment. |
segment_in_use | 409 | Segment in use | Remove the segment from the automations, broadcasts and segments listed in metadata first (segments with update_segment), then delete it. |
broadcast_not_found | 404 | Broadcast not found | Use a broadcast id from list_broadcasts. |
email_not_found | 404 | Email not found | Use an e-mail id from get_broadcast or get_automation; a new email exists here once its draft is saved. |
email_domain_not_found | 404 | Email domain not found | Use a domain id from list_email_domains. |
email_sending_disabled | 409 | Email sending disabled | E-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_exhausted | 402 | Email balance exhausted | Tell the account owner to top up the e-mail balance, then repeat the call. |
email_draft_not_found | 404 | No draft of this email | There 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_draft | 409 | The email was saved after your draft started | Tell 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_found | 404 | The draft does not keep that revision | Pick a to_revision from the draft’s history, or go back at most metadata.revision - 1 steps, and never more than 20. |
email_preview_unavailable | 503 | No live preview link | Show the user pictures of the email instead. |
automation_not_found | 404 | Automation not found | Use an automation id from list_automations. |
automation_inactive | 409 | Automation inactive | Turn the automation on with enable_automation, then run it again. |
automation_not_startable | 409 | Automation not startable by API | Only an automation with the manual or webhook trigger can be run; pick one in list_automations. |
automation_invalid | 422 | Automation invalid | The automation needs a valid trigger, which is set in the admin; enable it after that. |
run_in_progress | 409 | Run in progress | The contact is already in this automation (metadata.state); start it again only after that run ends. |
integration_not_found | 404 | Integration not found | Use an integration id from list_integrations. |
delivery_not_found | 404 | Delivery not found | Use a delivery id from list_integration_deliveries or list_event_subscription_deliveries of the same integration or event subscription. |
event_subscription_not_found | 404 | Event subscription not found | Use an event subscription id from list_event_subscriptions. |
event_subscription_limit_reached | 409 | Event subscription limit reached | Delete an event subscription with delete_event_subscription, or add the events to an existing one with update_event_subscription. |
delivery_not_redeliverable | 409 | Delivery cannot be redelivered | The 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_large | 413 | File too large | Send a file of at most 3 MB. |
image_type_not_allowed | 422 | File type not allowed | Send an image file. |
image_unsafe_svg | 422 | Unsafe SVG | Remove scripts and external links from the SVG, or send a PNG. |
image_url_unreachable | 422 | File could not be downloaded | Send a public http or https URL, or the file itself in data. |
image_unreadable | 422 | Not an image | Send an image file or its public URL. |
image_upload_link_invalid | 404 | Upload link expired | Get a fresh link from create_image_upload_link. |
image_source_required | 422 | File source required | Give exactly one of url and data, and name with data. |
Source: OpenAPI specification. Paths that start with /v1 are on https://api.getsitecontrol.com.