Getting started

Errors

When a request fails, the HTTP status says what kind of problem it is. Most error bodies add a message written for people, and many add a machine-readable code. This page lists the error shapes and codes the API returns, what each one means and what to do about it, and ends with the problems developers run into most.

How to handle an error

  1. Check the status code first. A refusal from the web servers in front of the API isn't JSON, so look at the status before you parse the body.

  2. Branch on code when the body has one. Change sets use reason instead.

  3. Show message to people, but don't parse it. Messages explain the problem and can change.

  4. Expect JSON from the API. Every error the API answers is JSON, whatever you send in Accept, and it never answers an error with a redirect. Only the web servers in front of it answer otherwise: a request body over 32 MB, or more requests than they allow from one address (see Rate limits).

For example, creating an article with a Read only key:

curl https://api.helpcenter.io/v1/articles \
  -H "apikey: $HELPCENTER_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{ "title": { "en": "Shipping times" } }'

The API answers 403 Forbidden:

{
  "status": "error",
  "code": "insufficient_scope",
  "message": "This action requires the content.write scope."
}

Error shapes

Body

Status

Where you meet it

{"status": "unauthorized", "docs_url": …}

401

The request has no key or token, or one the API doesn't accept. docs_url links the quickstart. Two more links, create_url and agent_docs_url, point an AI agent that has no key at creating a help center: see Migrate a knowledge base as an AI agent.

{"status": "error", "message": …}

400, 401, 403, 404, 409, 422, 500

Most errors from an endpoint, such as Article not found., and an image that couldn't be stored (500).

{"status": "error", "code": …, "message": …}

400, 402, 403, 404, 409, 410, 412, 422, 429, 503

Errors with a machine-readable code, sometimes with more fields. See Error codes below.

{"status": "error", "reason": …, "message": …}

402, 409

Change sets.

{"status": "validation_error", "message": …, "errors": {…}}

422

Validation on most endpoints, including GET /v1/categories, GET /v1/images and PATCH /v1/articles/{id}.

{"status": "validation_error", "errors": {…}}

400

Validation on GET /v1/articles, except a lang the help center doesn't have on a search, which answers 422 with "status": "validation_error", a message and errors.

{"<field>": […]}

400

Validation on POST /v1/articles.

{"message": …}

405, 429, 500

General errors: a method the path doesn't take, a rate limit, a failure on HelpCenter.io's side.

{"status": "error", "message": "Not found."}

404

An unknown path.

An HTML page

413, 429

A refusal from the web servers in front of the API: a request body over 32 MB, or more requests than they allow from one address.

Validation errors

Validation errors list the problems by field: every key of errors is a field you sent, and every value a list of messages. The envelope around them depends on the endpoint. Most endpoints answer 422 Unprocessable Entity, as here for a category name sent as a string:

{
  "status": "validation_error",
  "message": "The request could not be accepted.",
  "errors": {
    "name": [
      "The name must be a {locale: text} map — for example {\"en\": \"Billing\"}."
    ]
  }
}

GET /v1/articles answers 400 Bad Request without a message, here for limit=500:

{
  "status": "validation_error",
  "errors": {
    "limit": ["The limit field must not be greater than 100."]
  }
}

POST /v1/articles answers 400 with the fields at the top level, here for an article without a title:

{"title": ["The title field is required."]}

GET /v1/categories, GET /v1/images and PATCH /v1/articles/{id} answer 422 with the same envelope as the other endpoints. Here GET /v1/categories?limit=500:

{
  "status": "validation_error",
  "message": "The request could not be accepted.",
  "errors": {
    "limit": ["The limit field must not be greater than 100."]
  }
}

Bulk requests validate every item on its own, inside a 207 response. Read results: the top-level status is success even when every item failed.

{
  "status": "success",
  "results": [
    {
      "index": 0,
      "status": "error",
      "external_id": null,
      "error": {
        "code": "validation_error",
        "message": "The article could not be accepted.",
        "errors": {"title": ["The title field must be an array."]}
      }
    },
    {
      "index": 1,
      "status": "error",
      "error": {
        "code": "invalid_item",
        "message": "Each item must be an article object."
      }
    },
    {
      "index": 2,
      "status": "error",
      "external_id": null,
      "error": {
        "code": "invalid_argument",
        "message": "Unsupported language key \"fr\" provided."
      }
    }
  ],
  "meta": {"total": 3, "created": 0, "updated": 0, "failed": 3}
}

Status codes

Status

What it means

What to do

400 Bad Request

Validation on GET and POST /v1/articles, a language code your help center doesn't have (Unsupported language key "fr" provided.), or site_required.

Fix the request.

401 Unauthorized

No credential, or one the API doesn't accept: a missing, mistyped, deleted or expired key, a key whose creator is no longer an Owner or Admin of the help center or whose HelpCenter.io account was deleted, or an OAuth token that expired or was revoked.

Check the apikey header, or refresh the token.

402 Payment Required

The help center doesn't have this feature: plan_upgrade_required for requests through the MCP server, CHANGE_SETS_UNAVAILABLE for change sets.

Change the plan, or for change sets on Catalyst, request early-preview access. Retrying doesn't help.

403 Forbidden

The credential is valid but may not do this: insufficient_scope, site_forbidden, notes_forbidden, design_forbidden, role_forbidden, STAGING_UNAVAILABLE, upload_url_invalid, upload_url_revoked, api_key_required or custom_domain_not_in_plan, and for an AI agent's key agent_not_allowed, capability_locked or agent_scripts_forbidden. Also asking for commenters' email addresses with a Read only key.

See the code in the table below.

404 Not Found

Nothing with that id exists on the help center your credential acts on. That includes ids from other help centers and items in the Trash. A key whose help center was deleted gets The site this API key belongs to is no longer available. The design endpoints answer with a code, listed below.

Check the id, and which help center your key belongs to: GET /v1/sites tells you.

405 Method Not Allowed

The path exists, but not with this method.

Check the method in the reference.

409 Conflict

The request clashes with the current state: category_not_empty, STALE_ETAG, BASE_CHANGED, template_migration_required, nothing_to_publish, a change set reason, an external_id that another article holds or that another request is importing, an image that articles still use, an import that is running or was cancelled (import_running, import_cancelled, not_importable, main_language_changed), a domain in use or being changed (domain_taken, custom_domain_busy), or for an AI agent's key migration_in_progress, already_claimed or source_unavailable.

Read the body: it says what clashed, and often what to send instead.

410 Gone

An upload URL expired or was already used, or expired: an AI agent's key whose help center expired before anyone claimed it.

Create another upload URL with POST /v1/images/uploads. For expired, start again with POST /v1/agent/help-centers.

412 Precondition Failed

stale_draft: the design draft changed since the etag you sent, so nothing changed.

Read the draft again, make your change on top of it, and retry with the new etag.

413 Payload Too Large

The request body is over 32 MB. The web servers in front of the API refuse it, with a page that isn't JSON.

Send fewer or smaller files per request.

422 Unprocessable Entity

Validation failed, or the request is valid but can't be carried out, such as NOT_PUBLISHED, template_invalid, limit_reached, an import source that can't be read, or a redirect that can't be saved.

Fix the fields in errors, or follow the message.

429 Too Many Requests

You hit a rate limit, or a limit with a code: limit_reached (creating help centers or filing migration requests without an account, reading a migration request) or custom_domain_limit_reached.

Wait for Retry-After seconds. See Rate limits.

500 Internal Server Error

Something failed on HelpCenter.io's side. The body is {"message": "Server Error"}.

Retry later. If it keeps happening, contact support with the method, path, time and body of the request, never your key.

503 Service Unavailable

analytics_unavailable: the analytics are temporarily unavailable. capacity_reached or busy: no help center can be created without an account right now.

Retry after Retry-After seconds (300 for the analytics, 5 for busy). For capacity_reached, try later or file a migration request.

401, 403 or 404?

401 means the API doesn't know who you are. 403 means it knows, but your credential may not do this. 404 means there is nothing with that id on the help center your credential acts on: an id from another help center always answers 404, never 403, so an error never confirms that an id exists somewhere else.

{"status": "error", "message": "Article not found."}

An unknown id answers 404 with a JSON body on every route, such as Article not found. or Category not found., and an unknown path answers {"status": "error", "message": "Not found."}.

Error codes

These codes appear in the code field of REST API errors. The last five, marked "reason", appear in the reason field of change set errors.

Code

Status

What it means

What to do

insufficient_scope

403

The credential lacks the scope this endpoint needs. The message names it: This action requires the content.write scope. For the custom domain, an API key's message also names the setting to tick.

Use a Read & write key (for team notes, one with team notes access; for the design, one with design access; for the custom domain, one that an Owner or Admin allowed to manage the custom domain, with Allow managing the custom domain in Settings, under API keys), or ask the user to approve that scope for your app. See Scopes.

site_required

400

An OAuth token reaches more than one help center, and the request didn't name one. sites lists the ids it can reach. An empty sites list means it reaches none.

Send X-HCio-Site or ?site= with one of the ids. An empty list has two causes. The person's account owns no help center: connect your app from an account that owns the help center, or use an API key from that help center. Or every help center they shared has since been deleted: connect again and share one.

site_forbidden

403

The help center you named isn't one this token reaches, or its id isn't a number.

Use an id from GET /v1/sites.

plan_upgrade_required

402

A request through the MCP server for a help center that isn't on Growth or Catalyst. Adds feature, upgrade_url and plans.

Change the plan at upgrade_url. Calls you make to the REST API directly with an API key aren't affected.

notes_forbidden

403

The person behind the credential can no longer see team notes on this help center, which takes the Owner, Admin, Editor or Translator role.

Use a credential of someone who has that access.

design_forbidden

403

The person behind the credential can no longer edit this help center's design in the dashboard, which takes the Owner, Admin or Editor role.

Use a credential of someone who has that access. See Design API.

analytics_rate_limited

429

More than 6 analytics requests in a minute with this credential.

Wait for Retry-After seconds, and store what you read: most figures change once a day.

analytics_unavailable

503

The analytics are temporarily unavailable. Comes with Retry-After: 300.

Try again in five minutes.

category_not_empty

409

You are deleting a category that still holds articles, drafts included, or child categories. Adds articles_count and children_count.

Send on_orphan=uncategorize or on_orphan=reparent.

upload_url_invalid

403

The upload URL was changed, or isn't known.

Use the exact upload_url, or create another.

upload_url_revoked

403

The credential that created the upload URL can no longer upload images to this help center.

Create another with a credential that can.

upload_url_expired

410

The upload URL is past its expires_at, 15 minutes after it was created.

Create another.

upload_url_used

410

The upload URL was already used. Each one takes a single upload.

Create another.

STAGING_UNAVAILABLE

403

Staged changes aren't available on this help center: it isn't on the Catalyst plan.

Update the live article with PATCH /v1/articles/{id}, or upgrade to Catalyst.

NOT_PUBLISHED

422

You staged changes on an article that isn't published, so there is no live version to keep them apart from.

Update the article with PATCH /v1/articles/{id}.

ARTICLE_UNPUBLISHED

422

You staged changes on an article that was unpublished after changes were staged. Those staged changes are kept.

Publish the article again, or update it with PATCH /v1/articles/{id}.

STALE_ETAG

409

The staged changes changed since you read them. Adds scope and the current etag or shared_etag.

Read them again, then retry with the new value.

BASE_CHANGED

409

The live article changed after you staged your edits. Adds locale.

Read the article again, or publish with "force": true to overwrite the live version.

CHANGE_SETS_UNAVAILABLE

422

You sent change_set_id while staging changes.

Leave it out. Add the article to a change set with POST /v1/change-sets/{id}/items.

template_migration_required

409

The help center doesn't use the template editor yet, so the design API can't reach it. Adds customizer_url.

Ask the owner to switch it to the template editor, at customizer_url.

nothing_to_publish

409

You published a design draft that is the same as the live design.

Change the draft first.

stale_draft

412

The design draft changed since the etag you sent. Adds the current etag.

Read the draft again, make your change on top of it, and retry.

template_invalid

422

An operation in a design batch couldn't be applied, so nothing was saved. errors lists each problem with its operation, op, path and message.

Fix the operation the error names, and send the batch again.

unknown_theme

404

No theme with that key. The message lists the keys.

Use a key from GET /v1/template/themes.

component_not_found, not_found

404

You read a component, script or custom CSS block that isn't in the design draft.

Read the current ids with GET /v1/template.

version_not_found

404

No published version of the design with that id on this help center.

Use an id from GET /v1/template/versions.

role_forbidden

403

An OAuth token whose person's role on the help center doesn't allow this action. Adds role.

Ask one of the help center's admins to change the person's role, or use a credential of someone who has it.

api_key_required

403

An OAuth token on /v1/redirects, which takes only API keys.

Use an API key of the help center.

custom_domain_not_in_plan

403

The help center's plan doesn't include a custom domain. Adds upgrade_url.

The owner upgrades on the billing page.

domain_taken

409

Another help center already uses that domain.

Remove it there first, or contact support. See Custom domain.

custom_domain_busy

409

Another change to the help center's domain is still running. Nothing was changed.

Retry shortly. See Custom domain.

custom_domain_limit_reached

429

The help center has made 4 domain changes in the last month. Nothing was changed. Comes with Retry-After.

Wait for Retry-After seconds, or ask support.

import_running

409

The import is queued or running, so it can't be changed, run or cancelled now.

Follow it with GET /v1/imports/{importId} and try again once the run ends.

import_cancelled

409

The import was cancelled.

Scan its address again with POST /v1/imports. See Imports.

not_importable

409

You ran an import whose address the importer can't read (importable is false).

Move the content another way.

main_language_changed

409

The help center's main language changed after the import wrote into it, so a run would write nothing.

Switch the main language back in Settings, under Localization.

credentials_not_accepted

422

An AI agent's key sent credentials for an import. It imports public sources only.

Leave the credentials out; the owner can connect a private source from the dashboard.

host_busy, host_daily_limit

422

POST /v1/imports: other help centers are importing from that site right now (at most 2 scans or runs at once), or it has had 20,000 of the importer's requests today.

Scan again in a few minutes, or after 00:00 UTC; or file a migration request.

needs_credentials

422

The import source is private: a Zendesk help center behind sign-in, or a HelpDocs site that needs its API key. Adds platform.

Send the credentials the message names (not with an AI agent's key).

not_public, too_large, robots, unreachable, remote_error

422

POST /v1/imports couldn't read the source: it isn't public, it is larger than the importer takes, its robots.txt keeps crawlers out, or it didn't answer as expected. The message says which. Adds platform.

Follow the message; HelpCenter.io's migration team can move such a source.

source_not_redirectable

422

A redirect from that path would never be used: the help center answers the path itself.

Redirect another path.

target_not_found

422

A redirect points at a page of the help center that doesn't exist now, or isn't published and public.

Point it at the page's current address.

external_target_forbidden

422

A redirect points at another site, and the key isn't allowed to redirect to other sites. An AI agent's key never is.

Point it at a page of the help center. A redirect to another site needs a Read & write key that an Owner or Admin allowed to redirect to other sites, with Allow redirects to other sites in Settings, under API keys.

redirect_loop, too_many_hops

422

The redirect would make a loop, or a chain of more than 3 redirects.

Point each redirect at the final page. See Redirects.

limit_reached

422, 429

422: an unclaimed help center is full (500 articles, 100 categories or 500 MB of images and files; limit says which), or an import doesn't fit (adds room and articles_to_import). 429: a limit for your address, such as creating help centers or filing migration requests without an account, with Retry-After; an IPv6 address counts with the rest of its /64. Most add limit, max and migration_request_endpoint.

See Migrate a knowledge base as an AI agent.

name_blocked

422

A help center created without an account was given a name that contains a protected brand name.

Use your user's own product or company name.

capacity_reached, busy

503

No help center can be created without an account right now: as many are open as HelpCenter.io allows, or many are being created (busy, with Retry-After: 5). A migration request that needs more new help centers than can be held right now is refused as a whole, and nothing is filed.

Try again later, or file a migration request. For a migration request, try later or with fewer sources that need a new help center.

agent_not_allowed

403

An AI agent's key asked for something outside what it serves: its help center's content (articles, categories, images, imports, staged changes, change sets), its design (/v1/template, /v1/translations) and, once its owner has activated a plan, its redirects and custom domain. Before the claim, every other credential is refused the same way.

Use only those endpoints. Everything else is your user's, with an API key they create in Settings, under API keys.

capability_locked

403

An AI agent's key on redirects or the custom domain before the help center's owner has claimed it, verified their email address and activated a plan. Adds capability, requires and next_step.

Pass next_step.instruction on to the owner.

agent_scripts_forbidden

403

An AI agent's key tried to change the design's scripts or HTML. Nothing was changed. Adds changes.

Leave those parts out; the help center's team makes them in the Template Editor.

agent_css_url_forbidden

422

An AI agent's key tried to load a file in CSS, or a Hero background, from another host. Nothing was changed. The message names the address.

Use a path on the help center, a data: image, or an image stored with POST /v1/images.

migration_in_progress

409

An AI agent's key wrote to a help center that an open migration request holds. Reads still work.

Wait for the request to end.

already_claimed

409

An AI agent's key tried to delete, or file a migration request for, a help center its owner has claimed.

Nothing to do: it belongs to its owner.

source_unavailable

409

A migration request named an agent_key whose help center was claimed, expired or entered another request while the request was filed.

File the request without that source.

expired

410

An AI agent's key whose help center expired before anyone claimed it, and was deleted. Adds site_id.

Start again with POST /v1/agent/help-centers.

CHANGE_SETS_UNAVAILABLE (reason)

402

Change sets aren't available on this help center: it isn't on Catalyst, or doesn't have early-preview access yet.

Change the plan. On Catalyst, request access: in the dashboard, click Change sets, then Request access. Retrying doesn't help.

CHANGE_SET_FULL (reason)

409

The change set already holds 500 items. Items added before the limit stay added.

Put the rest in a second change set.

TOO_MANY_OPEN_CHANGE_SETS (reason)

409

The help center already has 25 open change sets.

Publish or delete one first.

CHANGE_SET_NOT_OPEN (reason)

409

The change set is being published, or was published, so its contents can't change.

Create another change set.

CHANGE_SET_NOT_SCHEDULABLE (reason)

409

You sent scheduled_for for a change set that is partially_published or failed. A publish of it was already tried, so it can't wait for a schedule.

Publish it now, without scheduled_for, to finish the release.

For example, deleting a category that still holds an article:

{
  "status": "error",
  "code": "category_not_empty",
  "message": "This category still holds content. Re-send with ?on_orphan=uncategorize or ?on_orphan=reparent to say where it should go.",
  "articles_count": 1,
  "children_count": 0
}

Codes inside results

Bulk responses report each failed item's code in results[].error.code. Change sets report their items' problems with a reason.

Where

Code

What it means

POST /v1/articles/bulk

invalid_item

The item isn't an article object.

POST /v1/articles/bulk

validation_error

The item failed validation. error.errors lists the problems by field.

POST /v1/articles/bulk

invalid_argument

The item uses a language code your help center doesn't have.

POST /v1/articles/bulk

external_id_busy

Another request is importing the same external_id. Retry the item shortly.

POST /v1/articles/bulk

persist_failed

The article couldn't be saved.

POST /v1/articles/bulk

limit_reached

An unclaimed help center is full. Stop, and file a migration request for the rest.

POST /v1/redirects/bulk

validation_error, source_not_redirectable, target_not_found, external_target_forbidden, redirect_loop, too_many_hops

The redirect couldn't be saved, as for POST /v1/redirects. The other items are saved.

POST /v1/images/bulk

storage_failed

The image couldn't be stored. Retry it.

POST /v1/images/bulk

import_failed

The image at the source_url was refused or couldn't be downloaded. The message says why.

Change set readiness.blockers[].reason

conflict, article_gone, category_gone

An item can't be published: the live article changed after staging, or the article or category was deleted. The change set can't publish until you fix or remove it.

Change set readiness.warnings[].reason

already_applied, locale_gap, staged_not_added

Worth a look, but publishing isn't blocked.

Change set rejected[].reason, when you add items

not_found

No article or category with that id on the help center. A published article with nothing staged is rejected with a sentence instead.

Errors outside the REST API

The other surfaces answer in their own formats.

OAuth

The authorization server on https://helpcenter.io answers with error and error_description, as OAuth 2.1 defines. See OAuth 2.1 for apps and AI clients.

error

Status

When

invalid_request

400, 404

A client sent no code_challenge, or a code_challenge_method other than S256, or a code, redirect_uri, code_verifier or refresh_token is missing or malformed (400). Dynamic client registration switched off (404).

invalid_client

401

Client authentication failed, the client isn't known, or, at the authorization endpoint, the redirect_uri isn't one the client registered.

invalid_grant

400

An authorization code or refresh token that is invalid, expired, already used, revoked or issued to another client; at the token endpoint, a redirect_uri that isn't the one the code was issued for; or a code_verifier that doesn't match the PKCE challenge. Using a code a second time also revokes the tokens its first use returned.

invalid_scope

Redirect

The authorization asked for a scope that doesn't exist.

unsupported_grant_type

400

A grant other than authorization_code or refresh_token.

access_denied

Redirect

The person clicked Deny on the consent screen.

invalid_target

400

A resource that isn't allowed, or that this grant didn't include.

invalid_redirect_uri

400

Client registration with missing or invalid redirect_uris.

invalid_client_metadata

400

Client registration with an unsupported grant_types or token_endpoint_auth_method.

temporarily_unavailable

429

More than 10 client registration requests in an hour from one IP address, refused ones included.

GET https://helpcenter.io/oauth/userinfo answers a bad token with 401 and {"error": {"code": "invalid_token", "message": …, "status": 401}}.

MCP server

https://mcp.helpcenter.io refuses a request before any tool runs with an HTTP status, and for a credential problem also a WWW-Authenticate header. Errors from the API behind a tool, such as plan_upgrade_required, reach the agent as the tool's result, with an explanation. See Connect an AI assistant to your help center.

Status

When

401, JSON-RPC error -32600

No credential: sign in with OAuth, or send an API key as Authorization: Bearer.

401, error="invalid_token"

The OAuth token was rejected, for example because it expired or wasn't issued for https://mcp.helpcenter.io.

403, error="insufficient_scope"

The token lacks a permission the tool needs, such as analytics.read. Reconnect and approve it.

400, JSON-RPC error -32000

An MCP protocol version the server doesn't support.

406, 415

The request lacks Accept: application/json, text/event-stream or Content-Type: application/json.

Public MCP server

The read-only server at https://<your help center>/mcp answers with JSON-RPC errors. See The public MCP server of a help center.

Error

When

404 {"error": "not_found"}

The help center has no public MCP server: it isn't public or hasn't been published yet, is limited to certain IP addresses or to your app, hides from search engines, has the server switched off, or isn't live.

429, JSON-RPC error 429

More than 120 requests a minute from your address, or 1,200 for the help center. Wait for Retry-After seconds.

413

A request body over 64 KiB.

-32700

The body isn't valid JSON.

-32600

A batch of messages (send one per request), or an unsupported MCP-Protocol-Version header.

-32601

An unknown method.

-32602

An unknown tool, or protocol parameters that don't match the request. Invalid tool arguments come back as a tool result with isError instead.

-32020, -32022

The MCP-Protocol-Version, Mcp-Method or Mcp-Name headers don't match the body, or name an unsupported protocol version.

Widget and embeds

The widget's requests to https://embed.helpcenter.io answer with status, message and code. See Content Security Policy and allowed origins.

Code

Status

When

WIDGET_NOT_FOUND

410

No widget has the app_id in your snippet.

SITE_AUTH_REQUIRED

403

The help center is private, or public but not published yet, and the request had no valid JWT. A reader's JWT doesn't open a public help center that isn't published yet: only its team, signed in, can see it. See Sign readers into the widget with a JWT.

SITE_IP_RESTRICTED

403

The help center only opens from certain IP addresses, and this visitor's isn't one of them.

SITE_UNAVAILABLE

403

The help center is unavailable, so FAQ sections show nothing.

SITE_NOT_PUBLISHED

403

A FAQ section was asked for on a public help center that hasn't been published yet. It serves FAQ sections once its team publishes it.

Single sign-on

Single sign-on returns no error codes. /sso/jwt answers in plain text: 400 Missing jwt parameter., 401 Invalid SSO token. (a claim of the wrong type included), 403 Single sign-on is switched off for this help center., or 500 SSO is not properly configured. Most other problems send the reader to the HelpCenter.io sign-in page. See Troubleshoot single sign-on.

Troubleshooting

Symptom

Cause

Fix

An HTML page where you expected JSON

The web servers in front of the API refused the request: a body over 32 MB, or more requests than they allow from your address.

Send smaller requests, or slow down. Check the status before you parse.

"The title field is required." although you sent a title

The request had no Content-Type: application/json, so the API didn't read the body.

Add the header.

401 with a key that looks right

A header other than apikey (api_key and X-API-Key aren't read), a deleted key, or a key whose creator's HelpCenter.io account was deleted.

Send apikey, or create a key.

404 for an article you see in the dashboard

The key belongs to another help center, or the article is in the Trash.

Check GET /v1/sites, or restore the article.

422 "The include email field must be true or false."

true or false in a query string or form field.

Send 1 or 0.

429 although you send fewer than 300 requests a minute

Single-article, staged, version and change set reads count against the 120 writes; exports, bulk requests and image uploads share a limit per IP address; the edge allows about 2 requests a second.

See Rate limits.

400 from POST /v1/articles, naming title.en or another language

A title that is empty or only spaces in one of the languages you sent.

Send text in every title you include; leave a language out to leave it alone.

403 insufficient_scope on /v1/custom-domain with a Read & write key

The key wasn't allowed to manage the custom domain.

Ask an Owner or Admin of the help center to tick Allow managing the custom domain for the key in Settings, under API keys.

422 external_target_forbidden on /v1/redirects

The to points at another site, and the key isn't allowed to redirect to other sites.

Point it at a page of the help center, or ask an Owner or Admin to tick Allow redirects to other sites for the key.

Was this article helpful?