Loading…
Loading…
Developers · API 1.10.1
Every error code the Poacher API and MCP tools return, what it means and what to do.
Every error has the same shape. code is stable; message is written for a person; docs links to the row below.
{
"error": {
"code": "insufficient_scope",
"message": "This request requires alerts:read. Ask the account owner to reconnect with that permission.",
"required_scope": "alerts:read",
"docs": "https://app.poacher.io/developers/errors#insufficient_scope"
}
}MCP tools return the same object inside a result with isError: true. On /mcp, a missing sign-in is an HTTP 401 and a missing permission an HTTP 403 with a WWW- header, so the client can ask the person to sign in or add the permission (authorization).
Fix the credentials or ask the person for more access. Retrying the same request will not help.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
unauthorized | 401 | The bearer key or token is missing, invalid, expired or revoked. Browser cookies never count. | Send Authorization: Bearer … with a current key, or sign in again through OAuth. |
invalid_token | 401 | On /mcp: the token was rejected. The WWW- header says where to sign in. | Start OAuth again from the resource_ URL in the header. |
insufficient_ | 403 | The key works but lacks the permission this request needs. required_scope names it. | Ask the person to reconnect with that permission, or create a key that has it. Do not retry. |
invalid_origin | 403 | A browser on another site sent an account request. Account requests are server-to-server. | Call from a server, script or desktop agent. Public documents allow any origin. |
invalid_host | 403 | The request reached Poacher through an unexpected host name. | Use https:/. |
public_ | 400 | A credential was sent to the public-only MCP address /api/mcp. | Connect to /mcp instead; it accepts sign-in. |
Correct the request and send it again.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
invalid_id | 400 | An ID in the path is not a positive whole number in range. | Use IDs exactly as the API returned them. |
invalid_ | 400 | limit or before is out of range. | Use limit 1–100 and a before cursor from next_before. |
invalid_json | 400 | The body is not valid JSON. | Send one JSON object. |
invalid_ | 415 | The body is not sent as JSON. | Set Content-. |
request_ | 413 | The body is over the limit: 2 KiB for edits, 16 KiB for paid-work requests. | Send fewer sources or shorter text. |
invalid_request | 400 | A field is missing or malformed. The message names it. | Fix the field the message names. |
idempotency_ | 400 | A quote or edit was sent without an Idempotency-Key. | Send a new random key of 16–100 letters, digits, - or _. |
idempotency_ | 409 | That idempotency key was already used for a different request. | Use a new key for a new request; reuse a key only to retry the identical request. |
revision_ | 428 | An edit was sent without If-Match. | Read the alert and send its edit_revision as If-Match: "…". |
method_ | 405 | This address does not accept that HTTP method. | Use the method shown in the reference. |
not_found | 404 | The endpoint does not exist, or the record belongs to another account. The two look the same on purpose. | Check the ID came from this account. |
invalid_name | 400 | The alert name is empty or too long. | Send 1–120 characters. |
invalid_edit | 400 | The edit asks for something the API cannot change. | Only name and status: "paused" can be edited here. |
Paid work is quoted first and approved with the quote’s exact request_hash. These errors keep an approval from applying to anything other than what was quoted.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
quote_expired | 409 | The quote is older than 15 minutes. | Make a new quote and ask the person again. |
quote_changed | 409 | The quote no longer matches its request_hash, or a different key tried to approve it. | Approve with the original key and the exact hash, or make a new quote. |
work_cancelled | 409 | The request was cancelled. | Make a new quote to try again. |
api_approval | 409 | This check or preview can no longer be approved. | Make a new quote. |
invalid_quote | 400 | The quote request is malformed. | Fix the field the message names. |
invalid_preview | 400 | The preview request is malformed: for example both url and sources, or a bad interval. | Send url or sources, not both; put intervals on each source. |
invalid_ | 400 | The changes for a saved-search preview are not supported. | Change only the settings listed for quote_. |
invalid_check | 400 | The check request is malformed. | Send alert_id, maximum_ and an idempotency key. |
invalid_ | 400 | A schedule’s minute offset or time zone is invalid. | Use 0–1439 minutes and an IANA time zone. |
invalid_source | 400 | A source URL is not a public web address Poacher can read. | Use a public https:// search or listing URL. |
invalid_url | 400 | The URL could not be read as a web address. | Send a full https:// URL. |
duplicate_ | 400 | The same source URL appears twice. | Send each URL once. |
incompatible_ | 400 | The URLs import different exact price filters. Nothing has started. | Use separate previews or alerts for them. |
source_ | 400 | A source needs settings that only the app can set. | Set up this source in the app. |
source_ | 409 | A saved source needs settings reviewed in the app first. | Open the alert in the app. |
check_ | 409 | An approved check for this alert is already queued or running. | Wait for it with get_check, then quote again if needed. |
api_daily_limit | 409 | The person’s daily API allowance cannot cover this ceiling. | Ask the person to raise the allowance in Developer access, or lower the ceiling. |
balance | 409 | The prepaid balance cannot cover the ceiling or minimum reserve. | Ask the person to add funds in the app. |
pricing_ | 409 | Paid work is not available on this deployment yet. | Check get_ later. |
The alert is in a state where this cannot run. Most of these need the person to act in the app.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
stale_alert | 409 | The alert changed since you read it. | Read it again and use the new edit_revision. |
alert_changed | 409 | The alert changed after the quote. | Make a new quote. |
configuration_ | 409 | The alert’s settings changed after you read configuration_. | Read the configuration again and review the change. |
configuration_ | 409 | The alert has too many sources to return at once. Nothing partial was returned. | Open the alert in the app. |
configuration_ | 409 | A source on this alert needs review in the app. | Open the alert in the app. |
alert_ended | 409 | The alert’s end date has passed. | Ask the person to extend or recreate it in the app. |
alert_held | 409 | The alert is paused for repair, billing or a result limit. | Ask the person to resolve the hold in the app. |
account_held | 409 | The account has a funding or billing hold. | Ask the person to resolve it in the app. |
source_ | 409 | The alert needs its own active sources before a check can run. | Ask the person to refresh the alert in the app. |
source_ | 409 | A source is not available right now. | Try later, or check the source in the app. |
brief_ | 409 | The saved matching brief needs review before it can be reused. | Send complete replacement criteria, or review the brief in the app. |
edit_ | 409 | This preview can only replace the alert it was made from. | Use the original alert, or start a new preview. |
draft_ | 409 | This preview was already used, or is a replacement draft. | Start a new preview. |
Only for keys with monitoring:manage, and only while finite monitoring is switched on.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
monitoring_ | 503 | Finite monitoring is switched off on this deployment. | Use start_ and let the person finish in Poacher. |
invalid_ | 400 | The creation request is malformed. | Fix the field the message names. |
invalid_update | 400 | The update request is malformed. | Fix the field the message names. |
invalid_ | 400 | The monitoring request is malformed: for example an expiry not in exact UTC milliseconds. | Use an expiry like 2026-, within 30 days. |
key_expiry | 400 | Monitoring would outlast the key. | End monitoring before the key expires. |
preview_ | 409 | The preview has not finished. | Wait for its final receipt with get_preview. |
preview_ | 409 | The preview is not a finished, settled, successful preview. | Run a new preview and wait for its final receipt. |
price_ | 409 | The preview lacks a complete running-price estimate. | Run a new preview. |
preview_changed | 409 | The preview changed after the quote. | Make a new quote. |
connection_ | 409 | A selected channel is no longer enabled or no longer belongs to this account. | List channels again and choose enabled ones. |
minimum_ | 409 | The alert’s monthly minimum has not been accepted. | Ask the person to accept it in the app. |
authorization_ | 409 | This monitoring permission has ended. | Quote new monitoring if the person wants it. |
Every new channel stays off until the person enters the code it received.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
invalid_type | 400 | The channel type is not one the API can add. | Use slack, discord, ntfy or sms. Email and browser notifications are set up in the app. |
invalid_ | 400 | The webhook, topic or phone number is not valid for that type. | Check the destination format in the reference. |
acknowledgement_ | 400 | An ntfy topic was added without confirming it is private. | Send ntfy_ once the person confirms. |
consent_ | 400 | A phone number was added without the person’s agreement to text messages. | Show the disclosure from get_ (channels.sms) and send sms_consent only after they agree. |
disclosure_ | 409 | The text-message disclosure changed since the person agreed. | Show the current disclosure again and send its version. |
sms_unavailable | 503 | Text messages are not switched on yet. | Check channels. in get_. |
invalid_code | 400 | The code is not six digits. | Ask the person for the 6-digit code. |
code_rejected | 409 | The code is wrong or expired, or too many wrong codes were sent. | Ask the person to check the code, or send a new one with resend_. |
channel_refused | 409 | The channel cannot be used: for example a number that replied STOP. | Ask the person to choose another channel. |
Wait, then retry the identical request.
| Code | HTTP | What it means | What to do |
|---|---|---|---|
rate_limited | 429 | A request limit was reached. Retry-After says how many seconds to wait. | Wait that long, then retry. Do not retry sooner. |
temporarily_ | 503 | Poacher could not complete the request. | Retry with backoff. Reuse the same idempotency key so nothing runs twice. |
View this page as MarkdownAPI version 1.10.1Changelog