> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dripstack.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Flow

> Wallet payment challenges, API-key credits, headers, and pricing semantics.

Paid article-summary routes support two payment models:

* **Payment-aware clients** use x402 with USDC on Base or Solana, or MPP on
  Tempo or Stripe (card / Link).
  A plain request returns HTTP `402`, then the client retries with payment
  credentials.
* **API-key clients** authenticate with
  [`Authorization: Bearer pk_drip_...`](/quickstart-api-keys) and spend
  account credits. API keys do not use the 402 wallet handshake.

Each first successful paid fetch of a post summary unlocks that post forever for
the paying subject. Later fetches of the same post return the live summary with
no charge and no new sale. Credits / API key / JWT / MCP OAuth share the same
Drip-user entitlement (including in-app chat paid fetches). x402 and MPP clients
should store `X-Drip-Unlock` / `unlockToken` from the first settle and send it
on free re-reads. If the token is lost but the same wallet (x402) or validated
MPP credential is presented again, the server detects the existing unlock, skips
the charge, and re-issues a token.

### Response fields

| Situation | `paymentInfo.protocol` | `amountUsd` | `unlocked` | `unlockToken` / `X-Drip-Unlock` |
| - | - | - | - | - |
| First x402 / MPP pay | `x402` / `mpp` | charged price | omitted | issued |
| Free re-read via `X-Drip-Unlock` | `unlock` | `"0.00"` | `true` | omitted (client already has it) |
| Free re-read via same wallet / validated MPP (lost token) | `unlock` | `"0.00"` | `true` | re-issued |
| First credits pay | `mpp` or `credits` | charged price | omitted | never |
| Credits free re-read | `unlock` | `"0.00"` | `true` | never |

A first API-key post response can report `protocol: "mpp"` when Drip completes
the credit-funded payment through MPP, or `"credits"` otherwise. The request
still spends the authenticated user's credits. Use the credit ledger to inspect
the debit; `spendSource` is not a response field.

Lifetime unlocks apply only to individual posts. Paid stock-picks bundles are
charged on each request and do not grant access to their source posts. Stock
Picks V2 also offers subscription access; see [Stock Picks](/stock-picks).

Invalid or revoked `X-Drip-Unlock` does not block payment: when a pay credential
is also present, the request falls through to that rail (or to a `402` challenge
if none).

## The 402 handshake for wallet clients

1. A plain request to a paid route returns `402` with two headers:
   * `WWW-Authenticate: Payment ...` — the MPP challenges for Tempo and Stripe
   * `PAYMENT-REQUIRED` — the x402 v2 challenge
2. Retry the **same request** through a payment-aware client, or manually with:
   * `Authorization: Payment <credential>` for MPP, or
   * a `PAYMENT-SIGNATURE` header for x402 v2.
3. On success (`200`), the response includes `synthesizedSummary` and
   `paymentInfo`.

The `402` response lets a wallet-aware client inspect the exact runtime price
before authorizing payment. For discovery-time estimates, publication post
listings include `priceCents`. The runtime challenge is authoritative.

<Warning>
  Treat a `402` as a "pay and retry" signal, not a failure. If a plain HTTP request returns `402`,
  retry it through the payment-aware client rather than surfacing an error.
</Warning>

A plain request returns a challenge rather than the paid summary:

```http theme={null}
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: <encoded x402 challenge>
WWW-Authenticate: Payment <MPP challenge parameters>
```

After a successful payment, the response identifies how the request was paid:

```json theme={null}
{
  "publicationSlug": "fabricatedknowledge.com",
  "slug": "ais-600b-question",
  "title": "AI's $600B Question",
  "synthesizedSummary": "The article examines whether projected AI revenue can justify rapidly expanding infrastructure spending...",
  "paymentInfo": {
    "amountUsd": "0.50",
    "protocol": "x402"
  }
}
```

## API-key credits

API keys are traditional bearer tokens created from the
[API keys page](https://dripstack.com/connect/api). Use them
when your agent or backend service should spend an account balance instead of
holding a wallet.

```bash theme={null}
curl \
  "https://dripstack.com/api/v1/publications/fabricatedknowledge.com/ais-600b-question" \
  -H "Authorization: Bearer $DRIP_API_KEY"
```

API keys spend available account credits, using signup credits before top-ups
for signed-in accounts. If the balance is too low, the paid route
returns `403` with `reason: "insufficient_credits"` instead of issuing a 402
payment challenge. See the [API-key quickstart](/quickstart-api-keys) for the
full setup and request examples.

## Inspect pricing before payment

List a publication's recent posts to compare prices before selecting one:

```bash theme={null}
curl "https://dripstack.com/api/v1/publications/fabricatedknowledge.com?limit=5"
```

```json theme={null}
{
  "posts": [
    {
      "slug": "ais-600b-question",
      "title": "AI's $600B Question",
      "publishedAt": "2026-06-14T12:00:00.000Z",
      "priceCents": 50
    }
  ]
}
```

`priceCents` is useful for selection and agent spending limits. When requesting
the paid route with a wallet, inspect the returned `402` challenge before
authorizing payment because it contains the live price.

## Discovery pricing vs runtime pricing

The OpenAPI discovery document exposes `x-payment-info.offers[]` on paid routes.
These offers are **advisory** — they may list Base or Solana USDC (x402), Tempo,
and Stripe charges, or catalog floor prices.

The **runtime `402` challenge is authoritative**. Per-post pricing comes from
the live challenge, and the price may scale with content — for example,
stock-picks charge a flat unit price times the number of distinct attributed
source articles in the response. Always trust the live `402` over publication
listings or discovery offers.

## Status codes

| Status | Meaning | Action |
| - | - | - |
| `200` | Summary returned; charged on first unlock | Read `synthesizedSummary` |
| `402` | Payment required | Retry the same request through a payment-aware client |
| `403` | Insufficient account credits (API keys) | Top up the credit balance |
| `404` | Content not found | Do not pay; verify the publication / post slugs |
| `503` | Summary not ready (`summary_not_ready`) | Retry later; no payment challenge is issued |

<Note>
  A `404` and a `503` never carry a payment challenge — do not pay on either. `503` means the
  summary is still being generated; retry shortly.
</Note>

For production handling, see [Errors & Retries](/concepts/errors-retries).

## Discovery

Prefer `GET /openapi.json` (OpenAPI 3.1) for route shapes, JSON schemas, and
paid-route `x-payment-info.offers[]` metadata. If OpenAPI is unavailable, use
`GET /.well-known/x402` for the paid resource list in `METHOD /path` form. The
root `x-discovery.ownershipProofs` field is a Drip vendor extension, not part of
core MPP discovery.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.