What an error looks like, every error any address can return and how to fix it, the limits, and how to retry safely.
Every tool page lists the errors only that tool returns. This page lists the ones any address can return, the limits that apply everywhere, and the rules for trying again.
Errors always give error (what went wrong), code (a name to branch on), where (the field or request path), tryThis (what to do next), retryable (whether waiting can help) and requestId (the value to find in Logs or quote to support). problems identifies individual fields when present. docs usually links to the section that explains the code. KEY_CREATOR_IS_A_MEMBER has no docs link; find it under Account and dashboard errors. why is an optional compatibility field for further explanation. Follow the HTTP status, Retry-After and tryThis when retrying.
A failed request answers with an HTTP status (a number that sums up the result, such as 404 for not found) and a JSON body explaining what went wrong and what to do next.
{
"error": "The request body could not be used.",
"code": "INVALID_FIELD",
"where": "/sellerNotes",
"retryable": false,
"requestId": "dc2a9e33-c568-4c37-a101-78846411bc02",
"tryThis": "Fix each place listed in problems, then send the request again.",
"docs": "https://business.pcific.ai/docs/api-errors#doc-invalid-field",
"problems": [
{
"path": "/sellerNotes",
"problem": "\"sellerNotes\" must be text.",
"tryThis": "Send \"sellerNotes\" as a string in quote marks."
},
{
"path": "/images/0",
"problem": "This photo id is not one of yours.",
"tryThis": "Upload the photo again and use the id the upload gives you."
}
]
}4xx means the request needs fixing before you send it again. 5xx means the problem is on PCIFIC's side: wait and try again. 429 means you sent too much too fast: wait the number of seconds in the Retry-After header. Always branch on code, never on the wording of error.
Each code below, and each tool's own codes, has a section of its own on the errors pages, starting with the mistakes integrations make most often.
| Code | HTTP | Why it happens | How to fix |
|---|---|---|---|
TEST_AI_MODE_MISMATCH | 400 | A listing or review was started in a different AI mode from this follow-up request. | Keep X-PCIFIC-Test-AI: stub on synthetic jobs. Remove it on real-AI jobs. To change mode, start a new job. |
INVALID_TEST_AI_MODE | 400 | X-PCIFIC-Test-AI is not stub, or was sent with a live key. | Send X-PCIFIC-Test-AI: stub with a test key for a free synthetic load test, or remove the header to use real AI. |
MISSING_API_KEY | 401 | The Authorization header is missing or has no API key. | Send your key as Authorization: Bearer <key>. If you do not have a key, create one under API keys in your PCIFIC dashboard. |
UNAUTHORIZED | 401 | The Authorization header is malformed or its API key is not recognised. This response does not say whether an unrecognised key was ever issued. | Send the key as "Authorization: Bearer <key>" with nothing else in the value. Copy it again from where you stored it. If it is lost, make a new key on the API keys page. |
KEY_REVOKED | 401 | The key was cancelled on the API keys page. A cancelled key can never work again. | Make a new key on the API keys page and put it wherever the old one was stored. |
KEY_EXPIRED | 401 | The key passed the expiry date it was given when it was made. | Make a new key on the API keys page and put it wherever the old one was stored. Choose a longer lifetime if you want the key to last longer. |
BUSINESS_SUSPENDED | 403 | PCIFIC has suspended your business, so none of its keys work. The error says the reason PCIFIC gave. | The business owner should email support@pcific.co.uk to talk about it. |
LIVE_KEYS_OFF | 403 | PCIFIC has switched off live keys to block requests from your business. | PCIFIC approves your account before you can make keys. Approved company email domains and accepted team invitations skip the wait. Account approval is the only approval from PCIFIC. To go live, choose Live key on the API keys page and press Activate live key; live calls spend credits bought from PCIFIC. Staff can suspend and restore live-key access (LIVE_KEYS_OFF). If blocked, use a test key and contact PCIFIC support about the block. |
KEY_NOT_ALLOWED | 403 | Either a test key lacks the permission this address needs, or a live key tried to change tool settings or listing fields. Live keys can read those but never change them. | For a test key, open API keys, choose Edit on the key and tick the permission tryThis names. For a live key, make the change on the dashboard or with a test key that has the permission. |
MARKETPLACE_ID_REQUIRED | 400 | Your business has more than one shop, and the call does not say which one it is for: marketplaceId is missing from the address. Nothing was changed or charged. | List your shops with GET /api/v1/marketplaces and add ?marketplaceId=<id> to the address, for example /api/v1/safeguard/settings?marketplaceId=<id>. Send it on every call from then on. |
MARKETPLACE_NOT_FOUND | 404 | marketplaceId names a shop your business does not have: a typo, a deleted shop, or another business's shop. | List your shops with GET /api/v1/marketplaces and use one of their ids. |
INVALID_ADDRESS | 400 | A part of the address could not be read, such as a version number that is not a whole number, or a category name that is not percent-encoded (written with %2F for a slash). | Check the address. Version numbers are whole numbers, and a category such as Vehicles/Cars is written Vehicles%2FCars. |
INVALID_JSON | 400 | The body is not a JSON object (text in curly brackets), or is not JSON at all. | Send a JSON object and the header "Content-Type: application/json". The error shows an example of what the address expects. |
INVALID_BODY | 400 | The body could not be read as JSON for this address. | Send a JSON body with the header "Content-Type: application/json" and check the commas and quote marks. |
INVALID_FIELD | 400 | A field has the wrong type, is missing or is too long. problems lists each place, as a path such as /images/0, with its own tryThis. | Fix each place listed in problems, using its tryThis, then send the request again. |
INVALID_SETTING | 400 | A tool setting has the wrong type, is out of range or is too long. The message names the setting. | Send the setting in the form the message shows. The guide for the tool lists every setting and its limits. |
NOT_FOUND | 404 | There is nothing at this address, or no record with this id in your business. | Check the address and the id. A record from another business, or one that was deleted, is not found. |
METHOD_NOT_ALLOWED | 405 | The address exists but not for this kind of request, for example POST on an address that only reads. | Use the method the guide shows for this address: GET reads, POST starts work or publishes, PUT changes, DELETE removes. |
BODY_TOO_LARGE | 413 | The body is bigger than the website lets through for this address. Most JSON calls take up to 16 KB. Uploads take more (see Limits). | Send less in one request, or split the work over several requests. For an upload, send it as a file in the form the guide shows. |
RATE_LIMITED | 429 | A limit of requests per minute was reached: 120 requests that start work per key, 600 PixelTrace photo checks per key, 1,200 requests of any kind per key, or 1,200 requests from one network address. | Wait the number of seconds in the Retry-After header, then send the request again. Send requests one after another, and give each environment its own key. |
TEST_DAILY_CAP_REACHED | 429 | Your test keys have used this shop's daily cap of AI requests. PCIFIC's ceiling always applies, 200 per shop per UTC day by default, or your lower saved cap. | Wait until midnight UTC (the clock the cap resets on), or use a live key. If you chose a lower cap, you can restore PCIFIC's ceiling on the API keys page. Requests that failed on PCIFIC's side are not counted. |
SPEND_LIMIT_REACHED | 429 | A live key reached a daily, weekly or monthly spending limit that you set for this shop. That shop's requests that spend credits are refused until the limit is raised or the window starts again. Your other shops are not affected. | Raise or clear the shop's limit on the Usage page or with PUT /api/v1/spend-limits?marketplaceId=<id>, or wait for the window to start again (UTC). Test keys are not affected. |
OUT_OF_CREDITS | 402 | A live key's request would spend more credits than your business has. No work started and nothing was charged. | Contact PCIFIC support to add credits. Test keys keep working. |
SPEND_LIMIT_CHECK_FAILED | 503 | PCIFIC could not check your spending limits for a request that spends credits. No work started and nothing was charged. | Send the request again in a few seconds. If it keeps failing, contact PCIFIC support. |
CREDIT_CHECK_FAILED | 503 | PCIFIC could not check your credit balance for a request that spends credits. No work started and nothing was charged. | Send the request again in a few seconds. If it keeps failing, contact PCIFIC support. |
INTERNAL | 500 | Something went wrong on PCIFIC's side. | Send the request again in a moment. If it keeps happening, contact PCIFIC support with the time of the request. |
BACKEND_UNAVAILABLE | 502 | The website could not reach the PCIFIC API behind it. | Wait a few minutes and send the request again. Use the same Idempotency-Key if the call takes one. |
BACKEND_UNAVAILABLE | 503 | The PCIFIC API is not switched on or reachable right now. | Wait a few minutes and send the request again. If it keeps happening, contact PCIFIC support. |
BACKEND_UNAVAILABLE | 504 | The PCIFIC API took longer than the website waits for this address (15 seconds for most addresses, up to 60 for photos). | Send the same request again, with the same Idempotency-Key if the call takes one, so the work is not done twice. |
NOT_AVAILABLE_YET | 503 | You called an address PCIFIC has not built yet, for example one from an older guide or prompt. | Use only the addresses in the current guides. The list of every real address is at /openapi.json. |
PCIFIC approves your account before you can make keys. Approved company email domains and accepted team invitations skip the wait. Account approval is the only approval from PCIFIC. To go live, choose Live key on the API keys page and press Activate live key; live calls spend credits bought from PCIFIC. Staff can suspend and restore live-key access (LIVE_KEYS_OFF).
Every API response includes X-Request-Id. Every error body includes the same value as requestId. This opaque UUID is the Request ID you can search on the dashboard Logs page. Recognised-key requests, including network limits and website refusals, are recorded when the backend and its logger are available. Refusal logging bounds key lookups and database concurrency; a logging outage or overload can leave an ID without a Logs row. Requests with no recognised key have no business to attach to Logs. A backend outage cannot be saved in Logs; quote its ID and time to support. RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset report an enforced request window, its requests left at the time it was checked, and seconds until it resets. If several windows were checked, the one with the fewest requests left is reported, choosing the earliest reset for a tie. Network, key, work-starting, sign-in, key-link and PixelTrace limits use their actual counters; a test key's daily AI cap resets at midnight UTC. Sign-in reports its public network allowance; private per-email controls are not exposed. Rate headers are omitted on publicly cacheable responses, such as badges, so a shared cache cannot pass one network's allowance to another. Headers are also omitted when no public request allowance was checked, including disabled limits. They describe request counts, not credit balances or file size limits. In-memory limits apply per server and reset on restart; PixelTrace and daily test counts are stored in the database.
When calling from scripts, send a User-Agent header naming your app, for example User-Agent: MyMarketplace/1.0.
For JSON tool requests, we recommend sending Content-Type: application/json; requests without it are read as JSON. The same input validation, work limits and charging rules apply with or without the header.
HEAD is supported wherever GET is supported. It returns the same status as GET and no body. Unknown API addresses, including unsupported API versions, return JSON NOT_FOUND with the same error fields.
The plain-text changelog at /changelog.txt accepts ?since=YYYY-MM-DD. An invalid or impossible date returns 400 INVALID_SINCE with where=/query/since. Send a real date, or omit since for the whole feed.
Every /api/v1 address has these limits a minute: 120 requests per API key that start work (POST /api/v1/listings, /api/v1/safeguard/reviews, the answers and retry calls of both, /api/v1/ask-pcific, /api/v1/pixel-trace/captures), a separate 600 PixelTrace photo-check requests per API key (they do not use AI or the work-starting allowance), 1,200 requests of any kind per API key (enough to read results back every few seconds; it only stops runaway loops), and 1,200 requests of any kind per network address (an IP address; IPv6 addresses count per /64). Requests refused before work starts, including bad input, missing fields and wrong types, do not use the work-starting allowance or the daily test AI cap. They still count towards the general per-key and network request limits. Photo-check requests, including invalid photos, use their own allowance before the image is opened. PixelTrace also allows 600 group starts and checks combined per account per minute, across all its keys. One key can use the full 600 for checks when no groups are started; group starts still share the 120 work starts with other tools. Authentication failures still count towards the network limit. Past any of them the API answers 429 RATE_LIMITED, naming the exact limit reached, with a Retry-After header saying how many seconds to wait. Send requests one after another rather than all at once, and give each environment its own key.
| What | Limit | What happens past it |
|---|---|---|
| Requests that start work, per API key (excluding photo checks) | 120 a minute | 429 RATE_LIMITED with a Retry-After header |
| PixelTrace photo-check requests, per API key | 600 a minute, separate from work starts | 429 RATE_LIMITED with a Retry-After header |
| PixelTrace group starts and checks combined, per account | 600 a minute across all keys | 429 PIXEL_TRACE_TOO_MANY_REQUESTS with a Retry-After header |
| Requests of any kind, per API key | 1,200 a minute | 429 RATE_LIMITED with a Retry-After header |
| Requests of any kind, per network address | 1,200 a minute | 429 RATE_LIMITED with a Retry-After header |
| JSON request body | 16 KB for most calls | 413 BODY_TOO_LARGE |
| A Safeguard review request | 256 KB | 413 BODY_TOO_LARGE |
| Photos in one upload to Orbit or Safeguard | 12 photos, 15 MB each, 60 MB in all | A 4xx error naming the photo, before any work starts |
| A listing field file (one category) | 10 MB | 413 SCHEMA_TOO_LARGE |
| Fields in one category | A warning from 300, refused over 500 | 422 SCHEMA_INVALID naming the category |
| Categories in your listing fields | 20,000 | 422 TOO_MANY_CATEGORIES |
| Listing field files stored by your business | 200 MB and 100,000 files across all shops and published versions | 422 SCHEMA_STORAGE_FULL |
| A field's description in your schema | 1 to 2,000 characters | 422 SCHEMA_INVALID naming the field. It is never cut |
| Ask PCIFIC documents | 50 documents, 300,000 characters each, 2,000,000 in all, files up to 10 MB | A 4xx error naming the limit |
| Idempotency-Key header | 1 to 255 visible characters, answers kept 24 hours | 400 INVALID_IDEMPOTENCY_KEY |
| Time the website waits for PCIFIC | 15 seconds for most calls, up to 60 for photos and PixelTrace, 40 for documents and Ask PCIFIC | 504 BACKEND_UNAVAILABLE |
| AI requests from test keys | Capped per shop and UTC day: PCIFIC's ceiling is 200 by default, or your lower saved cap | 429 TEST_DAILY_CAP_REACHED |
Each tool page adds its own limits, such as the number of photos in a PixelTrace group.
Send X-PCIFIC-Test-AI: stub on Orbit, Safeguard and Ask PCIFIC requests with a test key. Keep sending the header on follow-up actions. A listing or review keeps its starting mode; a mismatch returns TEST_AI_MODE_MISMATCH. Start a new job to change mode. Live keys and other values are refused with INVALID_TEST_AI_MODE. Authentication, shop isolation, input and schema validation, request and work limits, safe retries, database queues, result polling, streaming and Logs still run. Only the AI execution is replaced with a fixed, synthetic result. No model, web search or paid lookup runs. These requests spend no credits and use none of the shop’s daily AI allowance, even when it is already full. Normal rate limits still apply, so pace the test and follow Retry-After.
The response header repeats X-PCIFIC-Test-AI: stub. Started jobs carry a synthetic warning, finished results include testAiStub: true, and Logs labels the request as a synthetic AI load test. Orbit and Safeguard jobs keep this mode across restarts and retries. Synthetic listings do not promise to fit the schema; synthetic reviews must never be treated as approval. This measures your request path and PCIFIC's queue and storage, not model quality, real AI latency, inference capacity or paid tool performance. Remove the header for normal AI requests. Safeguard, Orbit and Ask PCIFIC stay on release 2.0.0.
Sometimes you cannot tell whether a request worked: the connection dropped, or your server timed out. Sending it again could do the work twice. An Idempotency-Key (a unique value you choose for each piece of work) lets you send it again safely. PCIFIC does the work once and gives you the first answer again.
curl -X POST https://business.pcific.ai/api/v1/listings \
-H "Authorization: Bearer $PCIFIC_TEST_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f1c2b9e-7d3a-4c55-9a51-0e6b2f8d1c47" \
-d '{"notes":"iPhone 13 128GB, unlocked, good condition"}'Send an optional Idempotency-Key on every public request that changes data or starts work: all POST, PUT and DELETE operations in the API reference, including Ask PCIFIC, PixelTrace checks, uploads, documents, settings and cancellations. Read-only GETs and the camera link validity check do not need one. Keys stay optional so existing integrations continue working; without a key, each call runs independently and a retry can repeat work and credits. Use 1 to 255 visible ASCII characters, such as a fresh UUID per action, and save it with the request before sending. Retry the same method, address (including query), body bytes and Content-Type within 24 hours to get the original successful status and body with Idempotent-Replayed: true, without more work or credits. Keep Accept and X-PCIFIC-Test-AI mode unchanged too. Upload retries must reuse the original bytes, including a multipart form's boundary. A different request with the same key returns 422 IDEMPOTENCY_KEY_REUSED with a next step. While work is running, 409 IDEMPOTENCY_KEY_IN_USE and Retry-After: 2 mean wait and retry with the same key. Keys belong to your business and test or live mode, shared across rotated API keys of that mode. marketplaceId is part of the request. Camera calls use a separate scope tied to the camera credentials; resend the original cookie and signed headers as well. Confirmation can replay with its original signature after the browser clears its cookie. Only successful replies are kept. A 4xx refusal is not saved. A replay of an accepted Orbit or Safeguard start returns the original 202 ticket. Poll the returned runId or reviewId for the current result. Refused requests and failures release the key, so fix the named problem and retry. An Ask PCIFIC stream is saved only when its done event arrives: retries replay all original events from the beginning, including done, without another answer or charge. Replace any partial answer in your interface when replaying. Work with a key continues after a dropped connection. Site-only demos and unavailable placeholder routes are outside this API contract.
import { randomUUID } from "node:crypto";
// Persist this action before sending. Reload the same action after a crash.
const action = {
key: randomUUID(),
url: "https://business.pcific.ai/api/v1/ask-pcific",
body: JSON.stringify({ question: "How much is delivery?" }),
};
async function send(action) {
return fetch(action.url, {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.PCIFIC_API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": action.key,
},
body: action.body,
});
}
const response = await send(action);
// On a lost response, call send(action) again. For 409, wait Retry-After.
console.log(response.status, await response.json());import json, os, uuid, urllib.request
# Persist this action before sending. Reload it after a crash.
action = {
"key": str(uuid.uuid4()),
"url": "https://business.pcific.ai/api/v1/ask-pcific",
"body": json.dumps({"question": "How much is delivery?"}).encode(),
}
def send(action):
request = urllib.request.Request(action["url"], data=action["body"], method="POST", headers={
"Authorization": "Bearer " + os.environ["PCIFIC_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": action["key"],
})
return urllib.request.urlopen(request)
with send(action) as response:
print(response.status, json.load(response))
# On a lost reply, call send(action) again. For 409, wait Retry-After.| Code | HTTP | Why it happens | How to fix |
|---|---|---|---|
INVALID_IDEMPOTENCY_KEY | 400 | The Idempotency-Key header is empty, longer than 255 characters, or has spaces or characters that are not visible ASCII. | Send a new random value for each new piece of work, for example a UUID (a long random ID such as 3f2b8c1e-6a4d-4f7e-9b1a-2c5d8e9f0a1b). |
IDEMPOTENCY_KEY_IN_USE | 409 | A request with this key is still running. | Wait the 2 seconds in the Retry-After header and send the same request again. Once the first one finishes you get its answer. |
IDEMPOTENCY_KEY_REUSED | 422 | This key was already used in the last 24 hours with a different address, shop, body or X-PCIFIC-Test-AI mode. | Use a new key for a new request. Send an old key again only with exactly the same address, marketplaceId, body and X-PCIFIC-Test-AI mode. |