# Pay-per-request inference with MPP

This endpoint serves Boundless inference paid per request through an MPP session (a payment
channel) on Tempo. It runs on Tempo mainnet (chain 4217) and takes payment in USDC.e, MACH or OUSD:
real money moves. Deposits, charges and refunds are in real USDC.e, MACH or OUSD, the token the
session opened in.

- USDC.e  0x20c000000000000000000000b9537d11c60e8b50
- MACH    0x20c000000000000000000000f37de3740ADec032
- OUSD    0x20c0000000000000000000006a37DA5C996874BE

A session opens in one token, the one your wallet pays with; every token is priced 1:1 with
USD. nanocode-mpp pays USDC.e by default; MPP_CURRENCY=mach pays MACH, MPP_CURRENCY=ousd pays OUSD.
With `tempo request`, `--payment-token <symbol>` picks the token, e.g.
`--payment-token OUSD`; `--mach` is MACH's alias.

## Set up a client

The client is nanocode-mpp, a nanocode build that pays MPP sessions from a Tempo wallet.

1. Log in to a Tempo wallet on mainnet:

       tempo wallet login --network mainnet

2. Fund the wallet with a few USDC.e on Tempo mainnet. Keep it small: a session locks only its
   deposit, and the unspent part comes back when the session closes.

3. Install the client (Rust toolchain needed):

       cargo install --git https://github.com/emilianobonassi/nanocode-machines --branch master --bin nanocode-mpp --locked

4. Point it at this endpoint, list its models and run one:

       export MPP_ENDPOINT=https://api.inference.boundless.network/mpp MPP_NETWORK=mainnet
       nanocode-mpp models
       nanocode-mpp exec -m deepseek/deepseek-v4.1-flash "Reply with exactly: ok"
       nanocode-mpp -m deepseek/deepseek-v4.1-flash

   `MPP_NETWORK=mainnet` makes the wallet pay in USDC.e on chain 4217; a
   wallet on the other network cannot open a session here. `/spend` shows what each model cost.

## Closing a session

- nanocode-mpp closes its session cooperatively on exit, and the unspent deposit comes back at
  once. `MPP_KEEP_SESSION=1` keeps the session open for the next run.
- With the Tempo wallet, `tempo wallet sessions close` sends an on-chain close request. When the
  session has spend not yet settled, this endpoint answers with its own close within about 2-4
  minutes, settling that spend and refunding the rest. With nothing unsettled the endpoint has
  nothing to capture, so your wallet withdraws the deposit after the 900 s grace period.
- `tempo wallet sessions close --cooperative` closes at once, but the Tempo wallet currently
  needs a local secp256k1 session key for it; a wallet logged in with a P-256 key gets
  "cooperative close requires a local secp256k1 session access key". Use the on-chain close.

## What the endpoint serves

- POST https://api.inference.boundless.network/mpp/v1/chat/completions   OpenAI Chat Completions, paid
- POST https://api.inference.boundless.network/mpp/v1/responses          OpenAI Responses, paid
- GET  https://api.inference.boundless.network/mpp/v1/models             priced models, free; pricing is USD per 1M tokens

## How you are charged

An unpaid request gets 402 Payment Required with a `WWW-Authenticate: Payment` challenge. The
client opens a channel with a small deposit (suggested 1 USDC.e) and signs a voucher per request. Each
request first holds its worst case (every body byte as an input token plus the output limit),
then is charged the tokens the model actually used, at the listed prices; cached input is charged
at the cache rate. A request the model fails to answer is refunded. Closing the channel refunds
the unspent deposit to your wallet.

Not supported (refused before payment): `n` or `best_of` above 1, `previous_response_id`,
`conversation`, stored prompts and items, and images or files by URL (send them inline as
data: URLs).
