Source profileQuality 91/100Review permissions

inflowpayai/inflow-cli/skills/agentic-payments/SKILL.md

agentic-payments

Authenticate with InFlow and pay HTTP 402-protected resources via MPP (the `Payment` auth scheme) or x402. Use when the user invokes the `inflow` CLI or asks to log in / connect to InFlow.

Source repository stars
9
Declared platforms
0
Static risk flags
2
Last source update
2026-08-27
Source checked
2026-08-28

Decision brief

What it does: where it fits

Pay HTTP 402-protected resources on the user's behalf. InFlow speaks two payment protocols - MPP and x402 - but the flow is the same for both: shared setup (install, run, authenticate), then a router that picks the protocol from the seller's 402 header, then one Paying a 402 res…

Best for

  • Use when the user invokes the `inflow` CLI or asks to log in / connect to InFlow.

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/inflowpayai/inflow-cli --skill "skills/agentic-payments"
Safe inspection promptEditorial

Inspect the Agent Skill "agentic-payments" from https://github.com/inflowpayai/inflow-cli/blob/8461543fcc777ff062f70f47358921faf3647ba0/skills/agentic-payments/SKILL.md at commit 8461543fcc777ff062f70f47358921faf3647ba0. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Step 1: Pre-flight evaluation

    Review the “Step 1: Pre-flight evaluation” section in the pinned source before continuing.

    Review and apply the “Step 1: Pre-flight evaluation” source section.
  2. 02

    Step 2: Pay

    Before initiating the call, summarize the intent to the user in chat: amount, currency, resource URL, and the method/rail (MPP) or scheme/network (x402). The user verifies the canonical details on the approval screen; the chat summary is what they read first. Example:

    Before initiating the call, summarize the intent to the user in chat: amount, currency, resource URL, and the method/rail (MPP) or scheme/network (x402). The user verifies the canonical details on the approval screen; t…"I'm about to pay 0.10 USDC to api.foo.dev for /dataset.csv. Requesting approval next."Fast path (recommended). When the agent can block until the payment finishes, set --interval N and let the CLI run the whole flow in one call - probe, decode, prepare, await approval, replay against the seller, return t…
  3. 03

    Installing

    Install the signed native CLI through one of these channels:

    Install the signed native CLI through one of these channels:Current install instructions live at https://inflowcli.ai/.
  4. 04

    Running

    InFlow runs as a standalone CLI or an MCP server.

    inflow --llms (or --llms-full for parameter detail) - discover all commands. inflow --schema for a single command's JSON Schema.inflow --skill - print this playbook (no frontmatter) to stdout. Use it to paste into the system-prompt field of an MCP host that doesn't natively load skills: inflow --skill | pbcopy.Default output is toon. Override with --format ; for programmatic parsing prefer json (single document) or jsonl (line-delimited).
  5. 05

    Common commands / options

    The CLI is the source of truth for exact flags, enums, and output shapes - run inflow --schema for one command, or inflow --llms-full for everything. This playbook covers when and why, not exhaustive parameter lists; when you need a precise flag name, value set, or response shap…

    inflow --llms (or --llms-full for parameter detail) - discover all commands. inflow --schema for a single command's JSON Schema.inflow --skill - print this playbook (no frontmatter) to stdout. Use it to paste into the system-prompt field of an MCP host that doesn't natively load skills: inflow --skill | pbcopy.Default output is toon. Override with --format ; for programmatic parsing prefer json (single document) or jsonl (line-delimited).

Permission review

Static risk signals and limitations

Runs scripts

medium · line 29

The documentation asks the agent to run terminal commands or scripts.

*The CLI is the source of truth for exact flags, enums, and output shapes** - run `inflow <command> --schema` for one command, or `inflow --llms-full` for everything. This playbook covers *when and why*, not exhaustive parameter lists; when

Runs scripts

medium · line 52

The documentation asks the agent to run terminal commands or scripts.

A successful `auth status` returns `authenticated: true` plus `auth_method` (`device_token` or `api_key`), a truncated `access_token` preview (never the full token), `credentials_path`, `connection`, and possibly an `update` field. Run the

Network access

medium · line 91

The documentation includes network, browsing, or remote request actions.

authentication is required before payment terms can be inspected; use `inflow aep fetch <url>` for access-only requests

Network access

medium · line 119

The documentation includes network, browsing, or remote request actions.

| Resource completion command | `inflow mpp fetch <transaction_id> <url>` | `inflow x402 fetch <transaction_id> <url>` |

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score91/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars9SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
inflowpayai/inflow-cli
Skill path
skills/agentic-payments/SKILL.md
Commit
8461543fcc777ff062f70f47358921faf3647ba0
License
MIT
Collected
2026-08-28
Default branch
main
View the original SKILL.md

Agentic Payments

Pay HTTP 402-protected resources on the user's behalf. InFlow speaks two payment protocols - MPP and x402 - but the flow is the same for both: shared setup (install, run, authenticate), then a router that picks the protocol from the seller's 402 header, then one Paying a 402 resource section that covers both. A per-protocol delta table at the top of that section lists the handful of real differences (header name, credential name, filters, error codes); read your row, then follow the shared steps.

Installing

Install the signed native CLI through one of these channels:

ChannelCommand
macOS Homebrewbrew tap inflowpayai/tap && brew install --cask inflow
macOS/Linux hosted installercurl -fsSL https://inflowcli.ai/install.sh | bash
Windows PowerShell installerirm https://inflowcli.ai/install.ps1 | iex
Cross-platform shell compatibilitycurl -fsSL https://inflowcli.ai/cli | bash

Current install instructions live at https://inflowcli.ai/.

Running

InFlow runs as a standalone CLI or an MCP server.

MCP: add an inflow server to your MCP client config that runs inflow --mcp.

MCP mode exposes every CLI command as a tool. Call tools/list on the MCP server for the authoritative inventory; arguments mirror the CLI flags one-to-one.

Common commands / options

The CLI is the source of truth for exact flags, enums, and output shapes - run inflow <command> --schema for one command, or inflow --llms-full for everything. This playbook covers when and why, not exhaustive parameter lists; when you need a precise flag name, value set, or response shape, query the CLI rather than guessing.

  • inflow --llms (or --llms-full for parameter detail) - discover all commands. inflow <command> --schema for a single command's JSON Schema.
  • inflow --skill - print this playbook (no frontmatter) to stdout. Use it to paste into the system-prompt field of an MCP host that doesn't natively load skills: inflow --skill | pbcopy.
  • Default output is toon. Override with --format <fmt>; for programmatic parsing prefer json (single document) or jsonl (line-delimited).
  • Multi-step flows return _next.command - run it to continue.
  • --auth <path> identifies a legacy plaintext credential file for deletion; it is not a credential backend.
  • --api-key <key> or INFLOW_API_KEY=<key> is an alternative to device-flow auth.

Authenticate

Authentication is shared by both protocols - do it once, before either payment flow. Don't start a payment until the user is authenticated.

Credential-bearing commands require the encrypted local vault. If the CLI reports that the vault is uninitialized or locked, tell the user to run inflow vault unlock themselves in a terminal, then retry. Never ask for or accept the vault PIN or passphrase through chat, an MCP tool, a command-line flag, or an environment variable.

Check the current state first - the user may already be logged in:

inflow auth status

A successful auth status returns authenticated: true plus auth_method (device_token or api_key), a truncated access_token preview (never the full token), credentials_path, connection, and possibly an update field. Run the command to see the full shape.

If the response includes an update field, a newer version of inflow is published.

Surface and defer. Tell the user a newer version is available and share the install instructions at https://inflowcli.ai/. Then proceed with the current version. Only block on the upgrade if a subsequent command fails with VERSION_UNSUPPORTED (or an HTTP 426 from the API), at which point the upgrade is mandatory and you should not retry until it lands.

If authenticated is false, start the device flow:

inflow auth login --client-name "<your-agent-name>"

Replace <your-agent-name> with the name of your agent or application (for example "Personal Assistant", "Shopping Bot"). The device-authorization page in the user's browser displays this name when they approve the connection. Use a clear, unique, identifiable name.

The response includes a verification_url (present this to the user), a phrase, and a _next.command. Run that command immediately to poll until authenticated. Do not wait for the user to respond before starting the poll.

If your environment can't relay the verification phrase to the user while a separate polling command blocks I/O, use inline polling instead:

inflow auth login --client-name "<name>" --interval 5 --timeout 300

API key alternative: if the user provides an API key, set INFLOW_API_KEY=<key> in the environment (or pass --api-key <key> to any command) instead of running auth login. The API key takes precedence over a saved device token.

If auth status returns VAULT_LOCKED, authentication status is unavailable rather than unauthenticated. Tell the user to run inflow vault unlock themselves in a terminal, then retry auth status.

Which protocol? - start here

Before paying, decide which protocol the resource uses. You do not choose it - the seller's 402 challenge decides. Run one read-only, no-auth command and let it detect both:

inflow inspect <url>

inflow inspect probes the URL once and decodes both MPP and x402 challenges from the same 402. Read its detected array to pick the protocol. For MPP, also read each challenge's intent: use mpp subscribe for subscription and mpp pay for one-time charge.

If detected includes aep and also reveals a payment protocol, continue with the matching mpp pay or x402 pay; the payment commands perform AEP authentication before creating the payment transaction. If aep.blocked is true, AEP authentication is required before payment terms can be inspected; use inflow aep fetch <url> for access-only requests or ask whether to authenticate before attempting payment.

detectedPay with
["mpp"]inflow mpp subscribe <url> for a subscription challenge; otherwise inflow mpp pay <url>
["x402"]inflow x402 pay <url>
["mpp", "x402"]Use the matching MPP command - MPP wins when both are present
[] (seller still returned 402)Not InFlow-payable on this account. Stop and tell the user; check warnings for why.

If inspect returns outcome: "no-payment-required", the URL isn't paywalled - there's nothing to pay.


Paying a 402 resource

This section covers one-time MPP charges and x402 payments. MPP subscriptions use Subscribing to an MPP resource. Prerequisite: you are authenticated (see Authenticate). First find your protocol's row in the Protocol deltas table below - it names the 402 header that selected it, the matching model, the filter flags, and the Fetch command that completes the seller request. Everything else in this section applies to both protocols.

Sequencing. Run pre-flight before pay - pay fails or double-charges if the pre-flight checks didn't clear. inspect and decode are read-only and need no auth, so they may run before you authenticate if useful (e.g. sizing up a paywall first). If the seller requires AEP before payment, pay authenticates with the Service first, then creates the payment only after the legitimate 402 is available. Do not run a separate aep grant just to continue payment.

Protocol deltas

AspectMPPx402
Selected when the 402 carriesWWW-Authenticate: PaymentPAYMENT-REQUIRED (and no WWW-Authenticate: Payment)
Command prefixinflow mpp …inflow x402 …
Matching modelThe seller's challenge pins the rail - the buyer does not choose scheme/network/assetPay where the x402 acceptssupported.kinds is non-empty
Filter flags--payment-method, --intent, --currency, --rail, --instrument-id--scheme, --network, --asset, --asset-name
Resource completion commandinflow mpp fetch <transaction_id> <url>inflow x402 fetch <transaction_id> <url>
Replay header used by FetchAuthorization: Payment <credential> plus a non-colliding AEP credential when requiredPAYMENT-SIGNATURE: <encoded_payload> plus a non-colliding AEP credential when required
Diagnostic credential file flag--credential-file <path> on status--payload-file <path> on status
Idempotency---payment-id (see Step 2)
Cancel usesapproval_idapproval_id
Protocol-specific error codesPAYMENT_FAILED, PAYMENT_EXPIRED, PAYMENT_NOT_ACCEPTEDAPPROVAL_TIMEOUT, APPROVAL_FAILED, APPROVAL_CANCELLED

Throughout this section <mpp|x402> means "use your protocol's prefix." For the exact parameters and output shape of any command below, run inflow <command> --schema.

Step 1: Pre-flight evaluation

# 1. Parse what the seller will accept - read-only, no auth (both protocols in one probe)
inflow inspect <url>

# (Already have the raw 402 header from a prior response? Decode it directly instead of re-probing:)
inflow <mpp|x402> decode '<402 header value>'

# 2. List what the buyer's account can pay with (use the protocol from `detected`)
inflow <mpp|x402> supported

# 3. Check balances for the candidate currency/asset(s)
inflow balances list

inflow inspect returns what the seller accepts under its mpp and x402 keys - the price is each challenge's amount field (raw atomic units for x402; the asset is the on-chain contract address, not a symbol). decode parses a single raw header you already hold (and also accepts a base64url credential / receipt). supported returns what the account can pay with; balances list returns available per currency. Run the commands to see the exact shapes.

Decide whether you can pay (apply your protocol's matching model from the delta table):

ConditionMeaningAction
No payable match between the seller and the buyer's supported methodsNo payable railStop → NO_INFLOW_MATCH. Tell the user the seller's rails aren't supported by their account.
A match exists, but balances.available < amount for every matchRight rail, not enough fundsStop → run inflow deposit-addresses list, surface the address(es) in full, ask the user to fund a matching network.
A match exists and ≥1 match has balances.available ≥ amountPayableProceed to Step 2.

Optional filters narrow which offer to fulfil - optional, AND-combined, applied on pay, and an empty result fails with NO_FILTERED_MATCH (it does not fall through to a default order). One non-obvious case: MPP's --instrument-id picks how to fund (an instrument-rail / fiat challenge), not which challenge. For the exact filter flags and accepted values per protocol, run inflow <mpp|x402> pay --schema.

Decimal precision. balances.available and the challenge/amount value are decimal strings preserving BigDecimal precision. Never parse them to a JS Number - that drops precision. Compare as strings, or use a BigInt / decimal.js-style library.

Step 2: Pay

Before initiating the call, summarize the intent to the user in chat: amount, currency, resource URL, and the method/rail (MPP) or scheme/network (x402). The user verifies the canonical details on the approval screen; the chat summary is what they read first. Example:

"I'm about to pay 0.10 USDC to api.foo.dev for /dataset.csv. Requesting approval next."

Fast path (recommended). When the agent can block until the payment finishes, set --interval N and let the CLI run the whole flow in one call - probe, decode, prepare, await approval, replay against the seller, return the body:

inflow <mpp|x402> pay <url> --interval 5 --max-attempts 180

The result includes outcome, transaction_id, response_status, settled, the seller body inline (or output_saved_to if --output-file is set), and the now-consumed credential (credential for MPP, encoded_payload for x402). On the fast path the CLI has already replayed that credential to fetch the body - it appears in the result for reference only; do not replay it yourself. To surface approval_url before the call returns, add --format jsonl - frames stream line-by-line. With the default json (or toon), the agent only sees the final buffered result.

outcome values. A completed pay returns one of three terminal outcomes - branch on it, don't assume paid:

outcomeMeaningWhat to do
paidSettled and the seller returned 2xxDeliver the body to the user
no-payment-requiredThe resource wasn't paywalled, or was already paidTell the user nothing was charged; return the body
replay-rejectedPayment was approved (funds in transit) but the seller replied non-2xx on the replayDo NOT report success. Tell the user the seller's response failed; because the payment didn't complete, the in-transit funds are reverted to their InFlow balance. Offer to retry

Two-step path. Use this when the agent's host can't block I/O long enough for the user to approve (chat UIs that yield between turns). Drop --interval; the first call returns transaction_id + approval_id + approval_url + a _next Fetch command/tool input. Fetch owns polling and seller replay.

inflow <mpp|x402> pay <url>
# -> { "transaction_id": "txn_abc", "approval_id": "appr_xyz", "approval_url": "https://app.inflowpay.ai/approvals/appr_xyz", "_next": { "command": "<mpp|x402> fetch txn_abc <url> --interval 5 --max-attempts 180", "tool": "<mpp|x402>_fetch", "input": { "transactionId": "txn_abc", "resourceUrl": "<url>" } } }

Mind the two distinct ids: poll, replay, and resume all use transaction_id; cancel uses approval_id (inflow <mpp|x402> cancel <approval_id>). Both are returned by pay.

For non-GET requests, pass --method, --data, --header (repeatable):

inflow <mpp|x402> pay https://seller.example.com/api/widgets --method POST --data '{"sku":"widget-1"}' --header "X-Custom: value" --interval 5 --max-attempts 180

Idempotency (x402 only). Set --payment-id <id> whenever a retry on transport failure is possible - the server treats two requests with the same id as the same logical payment, so a retry after a network blip won't double-charge. Use a stable random opaque value generated once per intent; reuse the same id on transport retry; regenerate only when the user explicitly wants a fresh charge. Don't tie the id to wall-clock time - a date-based id silently double-charges on next-day "buy this again" requests. Without --payment-id, the server generates one each call - fine for one-shots, unsafe for retries. (Format constraints: inflow x402 pay --schema.)

inflow x402 pay <url> --payment-id "<stable-opaque-id>"

Sensitive / binary output. Fetch never exposes the one-time bearer credential (credential for MPP, encoded_payload for x402). For the seller's response body, --output-file <path> writes bytes to disk and replaces body / body_base64 with output_saved_to: <path> - pair with --no-show-body for binary content (PDFs, images, audio, datasets) so bytes never appear inline as base64:

inflow <mpp|x402> pay https://api.foo.dev/dataset.csv --interval 5 --max-attempts 180 --output-file /tmp/dataset.csv --no-show-body

Polling discipline. Persist transaction_id as soon as pay returns it. Then:

  • Run _next.command, or call _next.tool with _next.input, immediately. Don't wait for the user to confirm before polling starts.
  • If polling is interrupted - network drop, session bounce, user kills the agent - resume with inflow <mpp|x402> fetch <transaction_id> <url> --interval 5 --max-attempts 180. Only create a new transaction if the original expired (PAYMENT_EXPIRED for MPP, APPROVAL_TIMEOUT for x402), was denied/cancelled, or its credential is already consumed.
  • If POLLING_TIMEOUT fires before approval, ask the user whether to keep waiting or cancel - don't silently restart the poll.
  • If >12 minutes elapsed without a user response (≈3 min before the 15-minute approval window closes), surface that explicitly so they can act before the window closes.
  • If the user aborts ("nevermind", "cancel that"), call inflow <mpp|x402> cancel <approval_id> before exiting. Otherwise the approval sits pending for 15 minutes and triggers phantom notifications in the user's InFlow app.

Fetch sends a ready payment credential to the seller at most once per invocation. If Fetch returns PAYMENT_REPLAY_OUTCOME_UNKNOWN, tell the user the seller might have received or consumed the credential and do not automatically replay it.

When AEP is required, Fetch still sends the payment credential at most once. The final seller request carries both credentials without exposing either one in JSON output, logs, cache keys, or chat.

Limits

LimitValue
Approval window15 minutes from pay creating the transaction (--timeout overrides the polling deadline)
Polling stop conditionPolling ends at whichever fires first: --max-attempts (count, default 0 = unlimited) or --timeout (seconds, default 900 = the full 15-min window). The examples use --interval 5 --max-attempts 180 (= 900 s) so a copied command covers the whole window - --interval 5 --max-attempts 60 (= 300 s) would stop polling at 5 min, well before approval can land
Credential reuseOne-time credentials are consumed by seller replay. Existing subscriptions use fresh, short-lived credentials bound to the seller's current challenge.

Worked example (MPP)

A user asks the agent to fetch a paywalled dataset at https://api.foo.dev/dataset.csv.

Pre-flight: inflow inspect <url> reports detected: ["mpp"] with the seller's challenges; then inflow mpp supported (methods the buyer can pay with) and inflow balances list. The seller offers the inflow method in USDC; the user's 100.5 USDC balance covers the 0.10 USDC price. Summarize intent, then pay:

inflow mpp pay https://api.foo.dev/dataset.csv --interval 5 --max-attempts 180 --output-file /tmp/dataset.csv --no-show-body
# Persist transaction_id from the response in case polling is interrupted.
# Returns outcome "paid" with output_saved_to /tmp/dataset.csv.

"Approval requested - confirm in the InFlow app: https://app.inflowpay.ai/approvals/appr_xyz I'll keep polling. 15-min window."

Once the result arrives:

"Paid 0.10 USDC. Transaction txn_abc. Saved the dataset to /tmp/dataset.csv."

Two-step variant (host can't block): follow Step 2's two-step path; mpp fetch polls, attaches Authorization: Payment, and returns the resource body without exposing the credential.

Worked example (x402)

A user asks the agent to fetch a paywalled article at https://api.foo.dev/article-3.

Pre-flight: inflow inspect <url> reports detected: ["x402"]; the intersection lands on exact × solana:mainnet, and the user's 100.5 USDC balance easily covers the 0.10 USDC the seller requires. Proceed.

"I'm about to pay 0.10 USDC on Solana mainnet to api.foo.dev for /article-3. Your balance is 100.5 USDC - plenty. Requesting approval next."

inflow x402 pay https://api.foo.dev/article-3 --payment-id "<stable-opaque-id>" --interval 5 --max-attempts 180
# Persist transaction_id from the response in case polling gets interrupted.
# Returns outcome "paid"; body contains the article JSON.

"Approval requested - confirm in the InFlow app: https://app.inflowpay.ai/approvals/appr_xyz I'll keep polling. 15-min window."

Once the result arrives:

"Paid 0.10 USDC. Transaction txn_abc. Server returned: 'How to brew coffee - ...'"

Two-step variant (host can't block): follow Step 2's two-step path; x402 fetch polls, attaches PAYMENT-SIGNATURE, and returns the resource body without exposing the encoded payload.

Subscribing to an MPP resource

Use this flow only when inflow inspect <url> shows an MPP challenge with intent: subscription. Before initiating it, show the user the recurring amount and currency, billing period, expiration, seller reference when present, resource URL, and settlement rail. Each subscription option includes a stable option_id derived from its recurring terms. If multiple options are available, ask the user which one they want and pass that identifier to mpp subscribe; never select the first option implicitly.

inflow mpp subscribe <url> --option-id <option_id> --interval 5 --max-attempts 180

The user approves the immutable recurring terms. Successful activation settles the first period. Later access uses subscriptions fetch, which obtains a fresh credential for the current seller challenge.

If the host cannot wait for approval, omit --interval, retain the returned transaction_id, and run the returned _next.command. mpp fetch polls, activates the subscription, and returns the resource. After activation, use subscriptions fetch <subscription_id> <url>; the server decides whether the current billing period is already paid or requires one new charge.

Manage the buyer's subscriptions with:

inflow subscriptions list
inflow subscriptions list --status active
inflow subscriptions get <subscription_id>
inflow subscriptions fetch <subscription_id> <url>
inflow subscriptions cancel <subscription_id>

Obtain explicit user confirmation immediately before cancelling a subscription. Cancellation is immediate and does not refund a paid period. A cancelled subscription cannot obtain another access credential. Treat PAST_DUE as recoverable through a later collection retry; EXPIRED, CANCELLED, REVOKED, and FAILED are terminal.

MPP errors

All errors in agent mode are JSON with code and message fields and exit code 1. MPP-specific codes (shared codes are in § Shared errors). "What to tell the user" is the prompt to surface - don't dump the raw error:

Error codeRecoveryWhat to tell the user
PAYMENT_FAILEDinflow mpp status <transaction_id> for the precise state, then create a new transaction with inflow mpp pay. (Terminal failed state, or no credential produced.)"The payment didn't go through - it was declined, underfunded, or the transaction failed. Want me to try again, switch funding, or stop?"
PAYMENT_EXPIREDStart a new inflow mpp pay."The payment window expired before it was ready to settle. Want me to start a new one, or stop here?"
PAYMENT_NOT_ACCEPTEDinflow inspect <url> to re-check the challenge; adjust and retry.-

x402 errors

All errors in agent mode are JSON with code and message fields and exit code 1. x402-specific codes (shared codes are in § Shared errors). "What to tell the user" is the prompt to surface - don't dump the raw error:

Error codeRecoveryWhat to tell the user
APPROVAL_TIMEOUTinflow x402 status <transaction_id> for the precise reason, then create a new transaction."You didn't approve within 15 minutes, so the request expired. Want me to start a new payment, or stop here?"
APPROVAL_FAILEDSame recovery as APPROVAL_TIMEOUT (declined / insufficient funds in the matched asset / generic)."Approval didn't go through (declined or insufficient funds in the matched asset). Want me to try a different funding source, top up, or stop?"
APPROVAL_CANCELLEDSame recovery (cancelled via x402 cancel or server-side)."You cancelled the approval. Stopping here unless you want to start a new payment."
INVALID_PAYMENT_ID--payment-id violated the format (see inflow x402 pay --schema). Adjust or omit the payment id.-

Security & data handling

Applies to both protocols.

  • Treat OAuth tokens and API keys as secrets - never echo them. Use Fetch for approved payments so one-time payment credentials are attached to the seller request without being pasted back to the user.
  • Respect /agents.txt and /llm.txt on sites you browse.
  • Avoid suspicious 402 endpoints - if the domain doesn't match what the user asked to pay, or the price is different from expectation, stop and ask.
  • When displaying deposit addresses to the user, print the full address (don't truncate). Truncating breaks copy-paste.

Shared errors

These apply to both protocols (in addition to each section's protocol-specific codes). All are JSON with code and message and exit code 1. Where a command is protocol-specific, use your prefix (<mpp|x402>). "What to tell the user" is the prompt to surface - don't dump the raw error:

Error codeRecoveryWhat to tell the user
VAULT_LOCKEDStored authentication status is unavailable. Ask the user to run inflow vault unlock themselves in a terminal, then retry."Your InFlow vault is locked. Please unlock it in your terminal, then I can check authentication again."
NOT_AUTHENTICATEDNo saved device token and no --api-key / INFLOW_API_KEY configured. Run inflow auth login or set the API key env var.-
NO_INFLOW_MATCHSeller's rails aren't supported by the account. Fund a matching method/chain, or use a different seller."The seller wants <method/rail or scheme×network>, but your account can't pay on that rail. Either fund a matching method, or pick a different seller."
NO_FILTERED_MATCHA pay filter emptied the candidate list. Loosen the filter (flags per the delta table), or re-check the seller's unfiltered options with inflow inspect <url>."Your filter removed every option the seller accepts. Loosen it or re-check the seller's options with inflow inspect."
INVALID_402 / DECODE_FAILEDSeller returned 402 but the protocol's header was missing (INVALID_402) or unparseable (DECODE_FAILED). Verify the URL is payable; pass the raw header to `inflow <mppx402> decode` for the detailed parse error.
POLLING_TIMEOUT--interval polling reached its max-attempts or timeout. Retryable - resume with `inflow <mppx402> fetch <transaction_id> --interval 5 --max-attempts 180`.
PAYMENT_REPLAY_OUTCOME_UNKNOWNA credential-bearing seller request had an indeterminate transport failure. Do not automatically replay."The seller request may have received the payment credential, but the connection failed before we got a reliable response. I won't retry automatically because the credential may be consumed."
api_errorNon-2xx from the InFlow API on the plain data calls (balances, deposit-addresses); discriminate on httpStatus. 401 - saved auth rejected, re-run inflow auth login. 426 (VERSION_UNSUPPORTED) - upgrade and retry. 5xx - server-side; wait and retry. (Note: pay/status rejections instead surface the server's own code, e.g. INSUFFICIENT_FUNDS, or the protocol's terminal code - not api_error.)-
VERSION_UNSUPPORTED / HTTP 426Installed inflow CLI is below the minimum supported version. Install the current release from https://inflowcli.ai/, then retry; don't retry on the old version.-
transport_errorNetwork failure - check connectivity; retry.-

Out of scope

This skill covers programmatic HTTP 402 payments (MPP and x402) only. It does NOT handle:

  • Traditional merchant checkouts No PANs (credit card forms, hosted checkouts).
  • Card issuance or wallet management beyond balances list and deposit-addresses list.
  • Refunds, disputes, chargebacks - handled out of band via support.
  • Peer-to-peer transfers between users or wallets.
  • FX / currency conversion. Buyer logic matches the seller's accepted rails against the account's supported assets.

For any of the above, point the user to https://app.inflowpay.ai or support.

Further docs

Frequently asked questions

What to verify before installation and use

What does the agentic-payments source document cover?

Pay HTTP 402-protected resources on the user's behalf. InFlow speaks two payment protocols - MPP and x402 - but the flow is the same for both: shared setup (install, run, authenticate), then a router that picks the protocol from the seller's 402 header, then one Paying a 402 res…

How do I install agentic-payments?

The source record exposes this install command: npx skills add https://github.com/inflowpayai/inflow-cli --skill "skills/agentic-payments". Inspect the command and pinned source before running it.

Which permission-related actions were detected?

Static rules flagged exec-script, network in the source; the page lists the matching lines and excerpts.