# Pubrio API errors and error codes: what each answer means

This page lists each answer the Pubrio storefront gives that is not company or people data, with what it means and what to do. Answers before the payment step are free and say what to fix. A company lookup is 1 credit, priced at $0.01, and two answers come only after the payment step: the API's own 400 for a missing identifier, and a 200 whose `data` object is empty.

## At a glance

- **Endpoint:** `POST https://agents.pubrio.com/zcj/u02b4skj3plk/companies/lookup` with a JSON body holding `domain`, `linkedin_url` or `domain_search_id`.
- **Error format:** storefront errors carry their code in a top-level `error` field of a JSON body. Pubrio's API errors carry a numeric `code`, a `message` and `details`.
- **Free answers:** the 402 price quote, a 400 for invalid JSON, a 404 for a path not sold, a 405 for the wrong method, and the plan purchase errors. Nothing is charged until you pay a 402.
- **Paid answers:** after a 402 is paid, the call reaches Pubrio's API, and its own status and body come back, errors included.
- **Price:** a lookup is 1 credit, $0.01, or $0.009 on Scale.
- **Payment:** a 402 is the price quote, which you pay and retry. x402 and MPP are the wallet rails, both in USDC. A per-call lookup needs no account and no API key.
- **Retry unchanged:** only `payment_provider_unavailable`, with backoff.
- **Full purchase flow:** [the buyer skill](https://agents.pubrio.com/zcj/u02b4skj3plk/SKILL.md). Every code: [the error reference](https://agents.pubrio.com/zcj/u02b4skj3plk/errors.md).

## Answers before payment

### 402 payment required

This is the normal price quote for a call. The request:

```bash
curl -i -X POST https://agents.pubrio.com/zcj/u02b4skj3plk/companies/lookup \
  -H 'Content-Type: application/json' \
  -d '{"domain": "stripe.com"}'
```

The answer is a 402 whose body carries `payment` with an `id` and `amountUsd`, `usage` with the meter and quantity, the `plan`, and a `protocols` block with an `mpp` and an `x402` challenge. The same challenges arrive in the `payment-required` and `www-authenticate` response headers, so a standard x402 or MPP client can settle them without reading the body. Pay on one rail and resend the same request with the proof attached. A plain quote has no `reason`. A 402 that carries a `reason` names a specific problem: check the error reference before paying.

### 400 for a body that is not valid JSON

A lookup whose body is not valid JSON answers 400 with a single `error` field, and no price is quoted. The `error` text says the body is not valid JSON for its content type. Fix the JSON and resend.

### 404 for a path the storefront does not sell

`POST https://agents.pubrio.com/zcj/u02b4skj3plk/companies/nothing` answers 404 with a numeric `code`, a `message`, and `details` holding links to the manifest and llms.txt. Take the path from [the API reference](https://agents.pubrio.com/zcj/u02b4skj3plk/openapi.json) and send it exactly as written.

### 405 for the wrong method

`GET https://agents.pubrio.com/zcj/u02b4skj3plk/companies/lookup` answers 405 with a numeric `code`, a `message`, and `details.methods` listing the method the path accepts, next to the manifest and llms.txt links. Lookup operations take POST with a JSON body.

### 401 bearer required on a plan purchase

A purchase sent to `POST https://agents.pubrio.com/zcj/u02b4skj3plk/plans/{planId}/purchase` with no agent credential answers 401 with an `error` field, a `hint` and an `auth` block naming the recipe, the authorization server and how to present the token. This is `bearer_required`, and it arrives before any price is quoted. A bearer credential is the agent identity the storefront issues, and a wallet cannot supply one. Register at [auth.md](https://agents.pubrio.com/zcj/u02b4skj3plk/auth.md), then retry with `Authorization: Bearer <token>`, or with `ZC-Agent-Authorization: Bearer <token>` when paying over MPP.

### 400 for buying the pay-per-call plan

A purchase of the Pay per call plan answers 400 with an `error` field. The storefront's code for this case is `payg_not_purchasable`. Pay per call is not a plan to buy. Call the API directly and pay each 402.

### 404 for an unknown plan id

A purchase for a plan id that does not exist answers 404 with an `error` field. The storefront's code for an unknown plan id is `plan_not_found`. Take the plan's `purchase.url` from [manifest.json](https://agents.pubrio.com/zcj/u02b4skj3plk/manifest.json).

## Answers after payment

After a 402 is paid, the call is forwarded to Pubrio's API. Its own status code and body come back, including its errors.

### 400 from the API for a missing identifier

A lookup with the empty body `{}` went through the payment step and answered 400 with the API's `code`, `message` and an empty `details` object. The lookup takes at least one of `domain`, `linkedin_url` or `domain_search_id`. Check the body before you pay, since a missing identifier is rejected only after the payment step.

### 200 with an empty data object

A lookup for a domain Pubrio has no record of paid $0.01 and answered 200 with an empty `data` object. The response:

```json
{
  "metadata": {
    "is_enrichment_available": true,
    "parameters": null,
    "filters": {"domain": "no-such-company-zq7x.com", "language": "en"},
    "profile": null
  },
  "data": {}
}
```

A 200 does not mean a record was found. Check that `data` holds fields before you use it. `metadata.filters` shows the domain as the API applied it, which helps catch a typo before you try again.

### Other API answers on the lookup

| Status | Meaning | Action |
| --- | --- | --- |
| 400 | The request was malformed or had invalid parameters | Read `code` and `message`, fix the body, then resend |
| 429 | Too many requests in a time window | Wait for the window to reset, then retry |
| 500 | An unexpected error on the server | Contact support if it persists |
| `zc-usage-error` header | You were served the API's response, and the storefront could not bill the usage | Use the response. Don't retry |

## Answers when buying or drawing on a plan

Plans are bought once with `POST https://agents.pubrio.com/zcj/u02b4skj3plk/plans/{planId}/purchase` and a bearer credential. Calls then draw the balance down.

| Code | Meaning | Action |
| --- | --- | --- |
| `verified_email_required` (403) | Your human must claim your credential with a verified email before this plan can be bought. The Free trial, with $1 of credit, is such a plan. | Complete the Claim step in [auth.md](https://agents.pubrio.com/zcj/u02b4skj3plk/auth.md), exchange for a fresh token, then retry. Without the claim, every retry fails. |
| `free_plan_already_claimed` (409) | The free trial was already claimed for your human, by this agent or another one | Use the existing trial. `GET https://agents.pubrio.com/zcj/u02b4skj3plk/agent/entitlements` with your bearer lists it. |
| `amount_below_minimum` (400) | `amountUsd` is under the plan's `purchase.minimumUsd`: $50 for Starter, $495 for Scale | Send at least the minimum, in whole cents |
| `amount_below_card_minimum` (400) | The amount cleared the plan minimum but not the card floor of $0.55 | For a new card purchase, send at least `purchase.cardMinimumUsd` ($50 for Starter, $495 for Scale), or pay on a wallet rail |
| `usage_exhausted` | The plan's credit ran out | Top up with `POST https://agents.pubrio.com/zcj/u02b4skj3plk/extend`, your bearer and `{"amountUsd": "<whole-cent amount>"}`, or buy again |
| `settlement_failed` | The signed payment did not settle. `settlementReason` says why, such as `insufficient_funds`. | Fix the wallet, then send the request from the start for a fresh 402 |
| `payment_provider_unavailable` | A transient failure reaching the payment provider | Retry unchanged, with backoff |

## Frequently asked questions

### Which Pubrio answers cost money?

Only answers that come after you pay a 402. Quotes, invalid JSON, unknown paths, wrong methods and plan purchase errors are all free. A lookup that finds no record is charged as a normal lookup, and a lookup with no identifier is rejected only after the payment step, so check the body before paying and check `data` before using the result.

### Why did a lookup return 200 with no data?

Pubrio has no stored record for that identifier. The call still returns 200 with an empty `data` object and is charged as a normal lookup. Treat an empty `data` as "not found", and confirm the identifier in `metadata.filters`.

### Do I need an account or API key to call the lookup?

No. A pay-per-call lookup needs no bearer: it is paid at its 402 from a wallet over x402 or MPP. Card covers only calls of $0.55 or more. A bearer credential is needed only to buy a plan, claim the free trial or top up, and `bearer_required` comes from those calls.

### How do I tell whether a response was charged?

A paid response carries a `zc-billing` header that reconciles what you authorized and what you were charged. On a plan, it reports `chargedUsd` and `remainingCreditUsd`. A delivered response with no `zc-billing` header billed nothing.

### Which errors are safe to retry unchanged?

Only `payment_provider_unavailable`, with backoff. Every other answer needs a fix, a fresh 402 or a claim first.

## Keep reading

- [Buyer skill](https://agents.pubrio.com/zcj/u02b4skj3plk/SKILL.md): the full purchase flow
- [Error reference](https://agents.pubrio.com/zcj/u02b4skj3plk/errors.md): every storefront code
- [How to pay](https://agents.pubrio.com/zcj/u02b4skj3plk/payment.md): rails, plans and top-ups
- [Agent identity](https://agents.pubrio.com/zcj/u02b4skj3plk/auth.md): the bearer credential and the claim step
- [Catalog](https://agents.pubrio.com/zcj/u02b4skj3plk/manifest.json): live services, plans and prices

---

Updated 2026-11-04. All Pubrio guides: https://agents.pubrio.com/guides.md. Storefront: https://agents.pubrio.com/zcj/u02b4skj3plk/llms.txt.
