Connecting and authenticating
Check the request URL and theAPI-KEY header first.
An HTML page comes back instead of JSON
The request went to a path that no API endpoint serves, so it fell through to the web app’s HTML not-found page. Check that the URL starts withhttps://app.surferseo.com/api/v2/ and that the path matches the endpoint’s reference page (URLs and versions).
A JSON 404 with "reason": "route_not_found" in details means the prefix is right and the rest of the path is wrong.
401 although the key is in the request
Surfer reads the key only from the API-KEY header, so a key sent as Authorization: Bearer, in a query parameter, or under another header name is not seen. Send it as API-KEY: <your key> (Send the key with every request). If the header is right, check that you hold the current key (Get your API key).
403 with a valid key
The key is recognized, but the plan behind it has no API access, API access is not enabled for your organization, or on a v1 tool endpoint the plan lacks that tool. When authentication fails has the check for each case and says when to write to support.
404 on a workspace path
The workspace in the path is not one your key can use: it belongs to another organization or is not active. Pick an id whose state is active from List workspaces; Workspaces in the path has the rule.
The same shape with "entity": "content_editor" means the editor id is not in that workspace.
Requests that are rejected or come back empty
Use the response’sreason and details to identify the rejected input.
409 with Content editor must be in completed state
The Content Editor has not finished its analysis. Check the editor’s state with Get Content Editor. Continue when it is completed; when it is failed, read its error before you create another editor, which spends a credit (Content Editor states, Credits).
413 on a content update, or 400 with too_large on an outline submit
The body is over the 1,000,000 bytes that Update Content Editor content and Submit edited AI Article outline each read. Trim the document, for example by removing embedded images and inline styles, and send it again.
422 with quota_exceeded
The organization has used up the allowance the operation spends, or holds as many templates or voices as its plan allows; the message names the allowance, for example Content Editor quota exceeded or Auto-Optimize allowance exceeded. Credits says what each operation spends and what to do when an allowance runs out.
429 on a burst of requests
The request went over the rate limit. Wait the number of seconds in the Retry-After header, then retry, and spread bulk work instead of bursting (Over the limit).
An empty data list where Content Editors exist
Content Editor lists cover the 90 days before now unless you pass filter[inserted_after] or filter[inserted_before], so older editors fall outside the window. Move the window to the dates the missing editors were created (The 90-day window on Content Editor lists).
422 from AI Detector or Humanizer on v1
Either text is outside the length the tool accepts, or the tool refused the run; the body says which.
- For Detect AI content in a text, split text over 100,000 characters into shorter pieces.
- For Humanize text, skip text shorter than 128 characters.
- When
textis within its limit, read the JSON body.Quota exceededmeans the Humanizer allowance is used up (Credits).Unknown errorfrom AI Detector orFailed generation, please try again laterfrom Humanizer means the run failed: retry once, then write to support.
500 on a content read or update
GET .../content and PUT .../content answer 500 with "reason": "internal_error" when Surfer could not reach or back up the editor’s document.
- Retry the request after a moment.
- If it fails again for the same editor, write to support with the editor id.
Work that does not finish
Check the resource’s current state before you start another run.The AI Article or the Auto-Optimize job never reaches completed
An AI Article (an article Surfer writes inside a Content Editor) and an Auto-Optimize job (a rewrite Surfer applies to the editor’s document) both run in the background, and failed is final for both. Read the state on Get AI Article or Get Auto-Optimize job, then:
waiting_for_user_input: the article was created withmanual_outline: trueand waits for your outline. Submit it to resume writing; Generate an article with outline review has the steps.newfor a long time: the article waits for the editor’s guidelines to settle, and fails on its own if they never do.failed: start a new article or job. A new Auto-Optimize run counts toward your plan’s Auto-Optimize allowance; a new article spends an AI Article credit on Enterprise and some older plans, while other plans include AI Articles in the Content Editor (Credits).
The SEO score never leaves calculating
A failed recalculation leaves status at calculating, so a poll without a deadline never ends (Recognizing a fresh score).
- When your polling deadline passes or
content_editor.seo_score.failedarrives, write the content again with Update Content Editor content to start a new recalculation. - If the score stays at
calculatingagain, write to support with the editor id.
A v1 SERP Analyzer export answers 404 Not found. or has rows with empty values
Get search results and Get prominent terms answer the plain-text 404 Not found. while the query is still running, when the id is not one of your organization’s queries, and, for prominent terms, when no prominent words or phrases were found.
- Poll List SERP Analyzer queries for a workspace until the query’s
stateiscompleted.failedis final; v1 has no retry, so create a new query. - Fetch the reports.
state: a scheduled row is still being crawled, a failed row was not crawled, and both have empty values in the factor columns. SERP competitor exports has the full recipe.
Webhooks and integrations
Check the receiver’s response status and its verification key.No webhook arrives
A delivery counts only when the registered HTTPS URL answers2xx in time. Check, in order:
- Confirm the URL is public and uses HTTPS.
- Confirm the receiver answers
2xxbefore it does any work; Delivery has the deadline and the retry rules. - Check that the work you started sends the event you wait for (Which work sends events).
- Compare the key your receiver checks with the current verification key (Set up a webhook).
Requests from Make or n8n fail authentication
Surfer reads the key only from theAPI-KEY header. In the tool’s HTTP request, add a custom header named API-KEY with your key as its value instead of the tool’s built-in authentication options, and use the URL from the endpoint’s reference page (Send the key with every request).
When a fix does not hold
Remove your API key from anything you send, then write to [email protected] with:- The method and path, for example
PUT /api/v2/workspaces/123/content_editors/456/content. - The time of the request, with its time zone.
- The full response: status, headers, and body. The
x-request-idheader lets support find the request in Surfer’s logs.