REST API Errors and Retries
When a request to the CheckView REST API fails, the response tells you what went wrong and whether it is worth trying again. This page covers the error format, the status codes you are most likely to see, and how retries work with idempotency keys. If you are new to the API, start with REST API Getting Started.
Error Format
Every error uses the RFC 7807 Problem Details format:
{
"type": "https://api.checkview.io/errors/bad-request",
"title": "Bad Request",
"status": 400,
"detail": "Step 2: URLs with embedded credentials are not allowed",
"instance": "/api/v1/test-flows/abc-123/steps"
}
- type – A URI that identifies the kind of problem.
- title – A short summary of the problem type.
- status – The HTTP status code.
- detail – What went wrong with this particular request. This is the field to read first.
- instance – The path of the request that failed.
When a request body fails field validation, the response also includes an extensions.validation_errors list with one entry per field.
Every response carries an X-Request-Id header. Include it if you contact support about a failed request.
Status Codes
400 Bad Request
The request was rejected before anything was changed. Fix the request and send it again. Common causes:
- Validation errors – A required field is missing or a value has the wrong type or format. Check
extensions.validation_errors. - URL safety rules – Any URL you send (a website, a page, or a Go to URL step) must be a public web address. It is rejected if it:
- is not a valid URL,
- uses a protocol other than
httporhttps, - has a username and password embedded in it, such as
https://user:[email protected], - points to a private or internal network address, or to a domain that resolves to one,
- uses a domain that does not exist.
- URL variables in Go to URL steps – A variable such as
{{TEST_FLOW_PAGE_URL}}must be the whole URL, optionally followed by a query string.{{TEST_FLOW_PAGE_URL}}?x=1is allowed;https://example.com/{{TEST_FLOW_PAGE_URL}}is not. - Schedule days – A schedule’s
daysmust have between 1 and 8 entries, and must be either weekly days only (0to7, where both0and7mean Sunday) or exactly one monthly day (-1to-28, where-15means the 15th of every month). Weekly and monthly days cannot be mixed. - Deeply nested body – A JSON request body nested more than 64 levels deep is rejected.
401 Unauthorized and 403 Forbidden
- 401 – Your token is missing, has expired, or has been revoked. Generate a new one at Organization Settings → API Tokens.
- 403 – Your token is valid but does not have the scope or role that endpoint requires. Create a token with the scopes you need.
- 403 when inviting a team member – Invitations need an active or trialing subscription whose billing is not paused. The response includes
extensions.subscription_status. Reactivate or resume the subscription, then invite again. - 403 when accepting an invitation – Invitations can’t be accepted with a personal access token; the invited person signs in to CheckView to accept. Accepting also fails if the organization has no subscription or it was canceled.
404 Not Found
The resource does not exist, or it belongs to an organization your token cannot access. Check the ID in the path.
409 Conflict
A 409 has two meanings. Check the title field to tell them apart:
- Conflict – The resource already exists or is in a state that blocks the action, for example a website URL that is already added, or deleting a test flow while its test is running. Fix the cause and retry.
- Request In Progress – A request with the same
Idempotency-Keyis still being processed, or failed recently. See Idempotency and Retries below.
429 Too Many Requests
You have exceeded your organization’s rate limit. Wait the number of seconds given in the Retry-After header, then retry. The limits are listed in REST API Getting Started.
Team invitations have their own email limit. When it is reached, the response has the type https://api.checkview.io/errors/invite-email-limit, no Retry-After header, and a detail that says when to try again. extensions.retry_after gives the wait in seconds when it is known. An address can receive up to 3 invitation emails from your organization in 24 hours, and deleting an invitation does not reset that count.
502 Bad Gateway
A 502 from a URL or WordPress check means nothing was changed; retry with the same key. Other 502s (for example when a background job could not be started) may have partly completed; wait a moment and check the resource before retrying. A 502 from deleting a test flow file or screenshot is safe to retry with the same key.
500 and Other 5xx Errors
Something went wrong on our side. The detail field reads “An unexpected error occurred”. Wait a moment and retry. If the error keeps happening, contact support and include the X-Request-Id.
Idempotency and Retries
Send an Idempotency-Key header (for example, a UUID) with every POST, PATCH, and DELETE request so that a retry cannot perform the same action twice. Keys are scoped to your organization and your user, so they never collide with anyone else’s.
- Successful requests – The response is saved for 60 minutes. Sending the same key again within that time returns the saved response without running the action again.
- Requests rejected before anything changed – A request rejected with a 4xx error by the endpoint, or with an error raised before anything was changed (for example a 502 when a URL or the WordPress site could not be checked), releases its
Idempotency-Key, so a retry with the same key runs immediately. - Other failed requests – A 403 from a permission check (for example a token missing a scope) keeps the key for about 2 minutes, like other failures; a retry with the same key during that time gets 409 Request In Progress. To retry at once after such a failure, use a new key.
Use a new key for each new action. Reusing a key for a different request within 60 minutes returns the saved response from the first one.
Changes
September 27, 2026
- Stricter URL safety checks: URLs with an embedded username and password, and domains that do not exist, are now rejected with a 400, along with private network addresses and protocols other than
httpandhttps. - A variable in a Go to URL step must now be the whole URL, optionally followed by a query string.
- Schedule days are now validated: 1 to 8 entries, weekly days or one monthly day, not both.
- Request bodies nested more than 64 levels deep are rejected with a 400.
- When a URL or the WordPress site cannot be checked, the request now fails with a 502 before anything is changed, so you can retry it with the same key.
- A request rejected with a 4xx error by the endpoint, or with an error raised before anything was changed, now releases its idempotency key, so a retry with the same key runs immediately. A 403 from a permission check and other failures keep the key for about 2 minutes; a retry with the same key during that time gets 409 Request In Progress.
- Team invitation emails sent through the API are now delivered from [email protected]. Invitation email addresses are matched without regard to case.
- Inviting a team member now needs an active or trialing subscription whose billing is not paused (403 otherwise), and invitation emails are limited (429 with the type
invite-email-limit). - Accepting an invitation with a personal access token now returns 403; the invited person signs in to CheckView to accept.
Related Articles
- REST API Getting Started – Authentication, rate limits, and pagination
- Navigation Blocked – When a test step tries to open an address CheckView does not allow
- Scheduling Test Flows – How schedules work in the dashboard