# Get product recommendation evidence from DubbleBlack's Powder API

DubbleBlack's Powder Evidence API answers a shopping question with the commerce evidence Powder holds for it, the coverage of that evidence and an Evidence Score for its strength, and leaves the recommendation to you. Each query is one `POST https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/api/agent/evidence` request, priced $0.10, and the storefront first returns a 402, which is a price quote: pay it over x402 or MPP and retry the same request. You need no account and no API key.

## At a glance

- **Endpoint:** `POST https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/api/agent/evidence`, one question per request
- **Body:** `query` (natural language, up to 2,000 characters), `limit` (1 to 10, default 5) and `max_external_sources` (0 to 10, default 2)
- **Price:** $0.10
- **Payment:** a 402 price quote, paid over x402 (Base USDC) or MPP (Tempo USDC) and then retried
- **Response:** JSON with `evidence_available`, `evidence`, `coverage`, `provenance`, `evidence_score`, `limitations` and `errors`
- **Time:** a call takes seconds, not milliseconds. Set your client's timeout to match.
- **Full purchase flow:** [buyer skill](https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/SKILL.md)

## Request commerce evidence for a product question

1. Send the question without payment:

   ```bash
   curl -s -i -X POST https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/api/agent/evidence \
     -H 'Content-Type: application/json' \
     --max-time 60 \
     -d '{"query": "What calming CBD chews should I consider for my dog?", "limit": 3}'
   ```

   The storefront returns `402 Payment Required` with the price and a challenge for each rail, in the body and in the headers, so a standard x402 or MPP client can settle it.

2. Pay the quote with your x402 or MPP client, then resend the identical request with the proof attached. On x402 the proof goes in `x-payment`. On MPP it goes in `Authorization: Payment <credential>`:

   ```bash
   curl -s -X POST https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/api/agent/evidence \
     -H 'Content-Type: application/json' \
     -H 'x-payment: <signed x402 payload>' \
     --max-time 60 \
     -d '{"query": "What calming CBD chews should I consider for my dog?", "limit": 3}'
   ```

   The response is `200` with a JSON body. The example call paid $0.10 and took 14.2 seconds. In that call, `limit` was 3 and `evidence` held two records.

3. Read the response. It has this shape, with types shown in place of values:

   ```text
   {
     "schema_version": string,
     "generated_at": date-time,
     "evidence_available": boolean,
     "evidence": [ { "evidence_type": string, "signal_type": string, "observed_count": number,
                     "identity_granularity": string, "product_name": string, "brand": string,
                     "provenance": { ... }, "limitations": [string] } ],
     "coverage": { "state": string, "owned_evidence_available": boolean,
                   "external_evidence_attempted": boolean, "external_evidence_used": boolean },
     "provenance": [ { ... } ],
     "evidence_score": { "score": number, "band": string, "components": { ... },
                         "formula": string, "limitations": [string] },
     "limitations": [string],
     "stage_timings_ms": { "owned_retrieval": number, "external_provider": number, "total": number },
     "errors": []
   }
   ```

| Field | What it tells you |
| --- | --- |
| `evidence_available` | Whether at least one relevant, legitimate observable signal exists |
| `evidence` | The evidence records. Each one has its type, signal, observed count, identity granularity, provenance and limitations. |
| `coverage.state` | The coverage state (see the next table) |
| `evidence_score` | The strength and depth of the evidence on a 0 to 100 scale, with its band, components and formula. It can be `null`. |
| `limitations` | What the evidence cannot support |

| Coverage state | Meaning |
| --- | --- |
| Owned | Powder holds relevant evidence and returns it |
| Supplemented | Relevant evidence comes back at a broader or an extra level of granularity |
| External | Reserved for explicitly enabled external evidence |
| Gap | No relevant owned evidence was found. This is a successful response, not negative evidence about the product. |

The API reference lists the other request fields: `intent`, `vertical` (an optional routing hint), `category`, `brand`, `product_ids`, `gtins`, `skus`, `context`, `evidence_types` and `requested_identity_levels`.

## Set max_external_sources and your timeout

By default (`2`), the call may also try outside sources. Set `max_external_sources` to `0` to limit the call to Powder's own evidence:

```json
{"query": "What calming CBD chews should I consider for my dog?", "limit": 3, "max_external_sources": 0}
```

With the default setting, the example question took 14.2 seconds and paid $0.10. The same question with `max_external_sources` set to `0` took 6.8 seconds and paid $0.10. Each response's `stage_timings_ms` breaks the time down by stage, with keys such as `owned_retrieval`, `external_planning` and `external_provider`.

Set your HTTP client's timeout well above the slower case, for example 60 seconds (`--max-time 60` in curl). If a call times out after you have paid, treat the outcome as unknown. Reconcile the payment before you pay again.

## Limits and charges

- Powder returns evidence and leaves the decision to you. It does not choose a product. The Evidence Score measures how strong and deep the evidence is. It does not measure product quality, recommendation confidence or purchase probability.
- Observed conversions are reported as observed conversions, not as confirmed purchases.
- Each request covers one subject, or an explicit comparison of two subjects written in `query`. A comparison returns `comparison_subjects` with separate evidence and scores for each subject, and no winner is picked.
- `brand`, `brands`, `product_ids`, `gtins` and `skus` each take one value.
- These requests are rejected: `budget_min`, `budget_max` and `include_insufficient_evidence`, any field outside the schema, and ambiguous requests with several selectors.
- Current evidence covers companion-animal, general-retail/CPG and beauty categories. Powder is not a web search engine, a general catalog or a product availability service.
- `GET` does not return evidence. Every evidence call is a paid `POST`, with one 402 per call.
- Card pays a pay-as-you-go call only when the call costs $0.50 or more. Below that, pay on x402 or MPP, or draw from prepaid Credits.
- Credits cost at least $0.50 per purchase, or $0.50 by card, and every Credits purchase requires an agent identity. You buy them at `POST /plans/{planId}/purchase`, with the plan id from the catalog in `manifest.json`.

## Errors

| Response | Meaning | Action |
| --- | --- | --- |
| `400` | The body is invalid, uses a rejected legacy field, or is ambiguous or names more than two subjects | Fix the body against the API reference |
| `402` | The price quote | Pay and retry the same request, or stop |
| `settlement_failed` | The signed payment did not settle. `settlementReason` says why. | Fix the wallet, then send a fresh request for a new quote |
| `payment_consumed` | That payment has already been settled | Check whether the original request was delivered before paying again |
| `429` | Rate limit exceeded | Follow the documented retry hint, with a bounded number of retries |

## Frequently asked questions

### Does the Powder Evidence API recommend a product?

No. Powder returns the evidence it holds for your question, along with its coverage, provenance, limitations and an Evidence Score. A product named in `evidence` is not a recommendation. The score describes how strong and deep the evidence is, and you decide whether that evidence is enough for your recommendation.

### Do I need an account or API key to query Powder?

No. A pay-as-you-go call is paid at the request through its 402 price quote, and the signed payment is all the storefront needs. You need an agent identity only to buy prepaid Credits. The [identity document](https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/auth.md) covers how to register one.

### How much does a Powder evidence query cost?

Each query costs $0.10, and every call gets its own 402. Ten queries cost $1. Prepaid Credits start at $0.50, and calls then draw down that balance.

### Why does an evidence call take several seconds?

Each response's `stage_timings_ms` reports the time spent in `interpretation`, `owned_retrieval`, `external_planning`, `external_provider`, `assembly` and `scoring`. With the default settings, the example question took 14.2 seconds. With `max_external_sources` set to `0`, the same question took 6.8 seconds. Set your client's timeout to allow for several seconds either way.

### What does a gap coverage state mean?

A gap means Powder found no relevant evidence of its own for the question. It is a successful response, not an API failure, and it is not evidence against the product. Each call is paid before Powder answers, so a gap answer costs the same as any other call.

## Keep reading

- [Buyer skill](https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/SKILL.md): the full purchase flow
- [Powder Evidence API reference](https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/services/powder-evidence/openapi.json): every request field and the response schema
- [How to pay](https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/payment.md): rails, Credits and top-ups
- [Error reference](https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/errors.md): every error code and the action to take

---

Updated 2026-10-20. All DubbleBlack guides: https://agents.dubbleblack.com/guides.md. Storefront: https://agents.dubbleblack.com/zcj/dl8cvbfh8dap/llms.txt.
