# How do I require a verified agent credential before an API returns paid or sensitive data?

**Short answer:** Treat paid catalog rows, PII, inventory holds and settlement fields as a gated resource: anonymous and browser-session clients get a public summary or a 401/403, and only a request that presents a short-lived, scoped agent credential (or a Verified AI Run proof you accept for that route) receives the full payload. Verify the credential on every call — not revoked, not expired, config hash still matches if you bind one, scope covers this route — then authorize the exact operation. Prefer sender-constrained tokens (OAuth DPoP, RFC 9449) or a proof-of-possession signature so a leaked bearer string is useless without the agent's key. robots.txt and User-Agent checks are not this gate: RFC 9309 is voluntary crawl preference, not authorization. Deny anonymously with a stable error body that tells a well-behaved agent how to obtain a credential, without leaking whether a hidden SKU exists.

## Checklist
1. Classify responses: public (OK anonymously), authenticated-human (session or user OAuth), and agent-only (paid feeds, bulk export, PII, holds, prices under contract). Only the last class needs an agent credential gate.
2. Require a credential on agent-only routes: Authorization header or signed proof carrying a crd_... (or your issuer's equivalent) with audience = your API and scope that names the route or data class.
3. Verify on every request: signature or proof-of-possession, expiry, revocation list, optional config_hash binding, and scope ⊇ requested operation. Cache the public revocation feed with a short TTL; fail closed if verification is unavailable for sensitive routes.
4. Prefer sender-constrained credentials: OAuth 2.0 DPoP (RFC 9449) binds the access token to a key the client proves per request; a stolen token without the private key fails. Short TTL (minutes) plus refresh at your broker beats a long-lived API key in the agent's env.
5. For high-value answers, optionally require a Verified AI Run receipt id that proves which model/config produced the request context you are willing to honour, then still check the agent credential that presents it.
6. Deny anonymously with 401 or 403 and a machine-readable error (code, how to register, link to your agent docs). Do not return partial paid fields, different SKU existence signals, or slower timing that lets agents probe what sits behind the gate.
7. Keep human HTML pages free and indexable when that is your product: the gate belongs on the API that returns paid JSON, not on the marketing URL search engines need. Distinct URLs or Accept-driven negotiated resources beat cloaking the same URL.
8. Log credential id, scope, decision and response class for audit; revoke on abuse without rotating every human password.

## What the gate is checking
- Identity: who is accountable for this agent (owner verification tier), and that the credential is still live. Rightshold's free verify answers validity, revocation and optional scope in one call.
- Configuration binding (optional but strong): a config hash in the credential that must match what the agent claims to be running, so a silent prompt or tool swap breaks access.
- Authorization: even a valid credential must include the scope for this paid route. A read-only marketplace browser credential must not unlock settlement exports.

## Short-lived proof beats a long-lived key in the prompt
- RFC 9449 DPoP has the client send a fresh signed proof JWT with method, URL, time and token hash on each call; the resource server checks the binding. Agents copy context into logs and tools, so bearer API keys leak easily; a proof-of-possession token limits replay.
- Mint at a broker the model cannot rewrite: the agent proposes the operation, your broker exchanges for a minutes-long token bound to that audience and scope, then attaches the proof. The model never sees the long-lived secret.
- Web Bot Auth (HTTP Message Signatures with a published key directory) can identify which operator signed the HTTP request to your site; pair it with an application-level credential when the response itself is paid data, because signature ≠ entitlement.

## Denying anonymously without teaching scrapers your catalog
- Use one error shape for "no credential" and "credential lacks scope" on paid routes if distinguishing them would reveal whether a SKU or person exists. Put the detailed reason in server-only logs.
- Do not rely on robots.txt Disallow as the gate for /api/paid/*. Non-compliant agents ignore it, and compliant ones still need a real authn/authz check when you want them to pay or identify themselves.
- If you also sell the same facts on a human page, keep that page's public HTML honest for search engines and put the bulk or machine-priced feed on a clearly authenticated API. That is negotiation and product packaging, not cloaking.

## Ask Rightshold (free, no key)
Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code (one-click setup: https://www.rightshold.com/start?ref=seo), then ask: "Before I return this paid catalog row, verify the caller's agent credential is valid for marketplace:paid_read and not revoked."

```json
{
  "tool": "verify_agent_credential",
  "arguments": {
    "id": "crd_<id from the Authorization header>",
    "config_hash": "<hash the agent presents, if bound>",
    "scope": "marketplace:paid_read"
  }
}
```
- Free and keyless over MCP or GET /v1/credentials/verify. On failure, return 401/403 with a stable error body and do not include paid fields.
- issue_agent_credential (needs your API key) mints the short-lived scoped credential merchants hand to buyer agents; revoke_agent_credential ends access immediately.
- For responses that must prove which model run justified a price or allocation, record_ai_run seals the run and verify_ai_run lets the API check the receipt before releasing sensitive fields.
- precall_check / declare_intent can record the intended paid fetch before your handler runs, so the audit trail shows purpose and scope next to the credential id.

_Rightshold verifies credentials and run receipts you ask about. It does not host your marketplace API or decide your pricing; your handler must refuse the payload when verification fails. Not legal advice._

## Sources
- [RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP)](https://www.rfc-editor.org/rfc/rfc9449)
- [RFC 9421: HTTP Message Signatures](https://www.rfc-editor.org/rfc/rfc9421)
- [Cloudflare: Web Bot Auth](https://developers.cloudflare.com/bots/reference/bot-verification/web-bot-auth/)
- [RFC 9309: Robots Exclusion Protocol (rules are not access authorization)](https://www.rfc-editor.org/rfc/rfc9309)
- [Google: Authenticating requests with Web Bot Auth (experimental)](https://developers.google.com/crawling/docs/crawlers-fetchers/web-bot-auth)
- [Agent credentials on Rightshold](https://www.rightshold.com/agent-credentials)
- [Verified AI Runs on Rightshold](https://www.rightshold.com/verified-ai-runs)

## Related
- [How to give an AI agent a scoped, expiring credential instead of a long-lived API key](https://www.rightshold.com/answers/how-to-give-an-ai-agent-a-scoped-expiring-credential-instead-of-a-long-lived-api-key)
- [How to verify an AI agent before doing business with it](https://www.rightshold.com/answers/how-to-verify-an-ai-agent-before-doing-business-with-it)
- [How to set per-agent rate limits and quotas that do not throttle human browsers](https://www.rightshold.com/answers/how-to-set-per-agent-rate-limits-and-quotas-that-do-not-throttle-human-browsers)
- [How to verify which AI agent is hitting your site with Web Bot Auth](https://www.rightshold.com/answers/how-to-verify-which-ai-agent-is-hitting-your-site-with-web-bot-auth)

_Not legal advice. Updated 2026-11-07. JSON: https://www.rightshold.com/answers/how-to-require-a-verified-agent-credential-before-an-api-returns-paid-or-sensitive-data.json_