# Palate Agent Contract

Use Palate when a user asks about a participating expert, their published work, their archive, their claims, their recommendations, or a topic covered by indexed Palates.

Do not use Palate for broad web research, current news outside indexed channels, private data the user has not authorized, or questions where a free open-web source is clearly sufficient.

## Quickstart with an API key

This is the recommended path. No wallet and no quote step: a paid query spends the key owner's existing unlock or credit balance.

- Create a Palate API key in your Palate account settings.
- Base URL is `https://palate.inc`.
- Send the key on every request as `palate-api-key: palate_...`.
- POST to `/api/ask/query` for global, one-Palate, or multi-handle scoped search.
- `paymentMode` is required for API-key queries. Use `unlocks` or `credits` to choose which balance to spend.
- Use `@handle` mentions in the question to narrow search quickly, or pass `scope` explicitly.
- Use `GET /api/palates?limit=...&cursor=...` to discover a `<slug>` only when you want to pin the query to one Palate.

```http
POST /api/ask/query
palate-api-key: palate_your_key_here
content-type: application/json

{
  "question": "What should I understand from @handle?",
  "paymentMode": "credits"
}
```

The response is a synthesized answer with citations, a `queryId`, and the `charge` that was applied.

## Scopes

Use `/api/ask/query` when you want the same retrieval style as the homepage ask box:

- Omit `scope` or set `{"kind":"global"}` to search public indexed Palates globally. `@handle` mentions in the question narrow the search to those handles.
- Set `{"kind":"palate","slug":"<slug>"}` to query one Palate.
- Set `{"kind":"handles","handles":["alice","bob"]}` to query a few users. Use `@creator/collection` mentions in the question to scope through public collections.
- On-chain Tempo/x402 scoped queries use the standard payment challenge flow: send `rail`, receive the rail's `402` challenge header, pay with the rail SDK/client, then retry with the protocol credential.

```http
POST /api/ask/query
palate-api-key: palate_your_key_here
content-type: application/json

{
  "question": "What do @alice and @bob say about pricing?",
  "scope": { "kind": "handles", "handles": ["alice", "bob"] },
  "paymentMode": "credits"
}
```

## Modes

- `synthesized` is the default. You get a grounded answer plus a citation list, ready to present to a human.
- `raw` returns the ranked source chunks instead, so your agent can resynthesize in its own voice for its human. It works with API-key, Tempo, and x402 payment.

```http
POST /api/ask/query
palate-api-key: palate_your_key_here
content-type: application/json

{
  "question": "What should I understand from @handle?",
  "mode": "raw",
  "paymentMode": "credits"
}
```

A raw response returns `mode: "raw"` and a `chunks` array. Each chunk includes the chunk text, a relevance `score`, the `palateUrl` citation handle, and source metadata. Resynthesize from these chunks; do not substitute model knowledge.

## Discovery

- Use paginated `GET /api/palates?limit=...&cursor=...` only for expert or topic discovery.
- Filter to a short relevant set before showing options to a user.
- Never dump the full directory into a response.
- Query only Palates where the user has intent to ask that expert.
- Use `palate_list_channels` before adding an optional query channel scope.

## Citations

- Always include the `palateUrl` citations returned by the API.
- Never invent source URLs for private items.
- `sourceUrl` may be omitted for private channels.
- `palateUrl` is always resolvable and is the canonical citation handle.

## Caching

Do not assume retries are free. A successful query is charged. If a retrieval returns no relevant content the charge is reversed, but a fresh request is a fresh charge.

## Recurring Interest

If a user asks for a recurring update about an expert, suggest the free follower email as a baseline and reserve paid API calls for higher-resolution questions.

## Failure Handling

Surface failures plainly. Never substitute model knowledge as though it came from Palate. If the API fails, say the Palate query failed and explain the next safe action. If `paymentMode` is missing on an API-key query the request is rejected; add it and retry.

## Advanced: on-chain pay-per-query

Wallet-native agents without a Palate account can pay per query with stablecoins instead of an API key. This path uses protocol-native 402 challenges and supports both synthesized and raw query modes.

Quotes advertise supported rails:

- `tempo` for MPP Tempo USDC.
- `x402_base` for x402 over Base USDC.

`POST /api/ask/quote` and `POST /api/palates/<slug>/quote` are static metadata endpoints. They return the selected rail, fixed answer price, receiver, currency, and chain id; they do not mint a nonce and are optional. To pay, call `/api/ask/query` or the matching one-Palate endpoint with `rail`. If the request is answerable, Palate returns `402` with the rail's payment challenge header: `WWW-Authenticate` for MPP/Tempo, `PAYMENT-REQUIRED` for x402. Pay and retry with the protocol credential in a payment header. Successful responses include the rail's receipt header: `Payment-Receipt` for MPP/Tempo, `PAYMENT-RESPONSE` for x402.

```http
POST /api/ask/quote
content-type: application/json

{
  "rail": "x402_base"
}
```

```http
POST /api/ask/query
content-type: application/json

{
  "question": "What should I understand from @handle?",
  "rail": "x402_base",
  "walletAddress": "0x..."
}
```

## MCP

The same surface is available over MCP globally at `/mcp` and per Palate at `/{palate-slug}/mcp`:

- `palate_list_channels()`
- `palate_quote(rail)` where `rail` is on-chain only and is ignored when an API key is present
- `palate_query(question, scope?, paymentMode?, mode?, rail?, walletAddress?, channelIds?)`

Global MCP `palate_query` accepts `scope` with `kind` of `global`, `palate`, or `handles`. For on-chain MCP calls, a 402 is returned as JSON-RPC error code `-32042` with `data.challenges`. Retry with the payment credential in `params._meta["org.paymentauth/credential"]`; successful results include `_meta["org.paymentauth/receipt"]`.

```http
POST /{palate-slug}/mcp
palate-api-key: palate_your_key_here
content-type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "palate_query",
    "arguments": {
      "question": "What should I understand from this expert's work?",
      "paymentMode": "credits"
    }
  }
}
```
