Skip to main content
Glama

Pay for and call a service

pay_service
Destructive

Pay for a catalog service from your spend-capped delegation and return the vendor response. This charges real funds. Paid calls can take several seconds, including payment verification, service work and settlement; longer tasks can take more. Call get_service FIRST: its requestShape.endpoints[] lists the callable paths with their HTTP method and price, and each payServiceArgs is the slug/path/method to pass here, after replacing any pathParams placeholder in path with a real value. A bare slug reaches the service base URL, which for a multi-endpoint API answers 404 instead of a payment challenge; only a single-endpoint service is called by slug alone. Send the endpoint's payServiceArgs: they carry an example only when it is paid-run or challenge. A docs example (and its invokePath) is unverified — use it only deliberately, filling any path parameter with the entity you want; otherwise build body from the endpoint description or the provider's docs. method may be omitted: it is taken from the catalog endpoint matching path (POST when the catalog names none) and echoed back under request. To accept a live quote, pass its quoteId before expiresAt with the exact same call arguments; the Router uses that cached challenge and exact fee-inclusive total. Keep maxTotalCents as an independent ceiling. Repeating an identical call (same arguments, no fresh) charges nothing new: on a deployment running API 1.48 or later it is answered within 24 hours from the first call's stored result, or its pending answer; on an older deployment it comes back as already_paid. For an ASYNC service, where you submit once and then poll a status endpoint with the same id, set fresh: true on every poll INCLUDING THE FIRST: otherwise each later poll reuses the first poll's idempotency key and gets the first poll's stored answer (or already_paid) back, so the status never advances. fresh makes each poll a distinct, separately billed call (the merchant charges per status call). Leave fresh off the submit and off any retry of a call whose outcome is unsure, because with fresh a retry is not de-duplicated and is charged again. A completed call returns paid, upstreamStatus (the vendor's HTTP status) and response (its body). paid: true means a payment was attempted, not that it settled, so read payment.status (Settled, Issued or Failed): Issued is not confirmed yet, which is neither a failure nor a reason to retry, and Failed does not prove nothing was charged, so check deliveryStatus in list_payments before paying again. With a non-2xx upstreamStatus it may still have cost the merchant price. Outcomes to act on: {"status":"pending"} means a payment was attempted and the service is still working, so whether it went through is not known yet; call get_payment_result with its paymentId every few seconds instead of calling pay_service again. {"status":"already_paid"} means this call's idempotency key already carries a payment whose result is not replayed here (the original call failed, its 24-hour result expired, the requestId was reused for a different request, or the deployment predates result replay, API 1.48); nothing new was charged, and it does not by itself say whether the original succeeded. Read the original with get_payment_result (paymentId) or list_payments (pass its requestId). A new requestId starts a separate, separately charged purchase: use one only after that read shows the original failed and the human still wants the result. {"error":"payment_indeterminate"} means the charge may or may not have landed: check list_payments first, and to retry reuse the returned requestId verbatim without fresh so the retry stays idempotent. {"error":"per_call_max_exceeded"} means no charge; raise maxTotalCents only after a deliberate decision and retry with the same requestId. quote_not_found, quote_expired, and quote_mismatch are named no-charge quote refusals; quote again rather than paying unpinned. {"error":"payment_failed"} is a definite decline (see code, message and retryable). These charge nothing: {"payable":false} (not payable via the Router; no upstream URL is ever returned), service_not_found (wrong slug), catalog_unavailable and delegation_lookup_failed (transient; retry later), payment_not_started (too little time remained to start a payment; retry with the same arguments), no_delegation (call setup_delegation), router_controls_unavailable (the API behind this server is too old to enforce search, quoteId or maxTotalCents; tell the human instead of retrying without them) and credential_refused (re-authorize). A paid result also carries delegationId and budget, the spending budget after this call (capCents/spentCents/remainingCents, cents with up to four decimals), so to say what has been spent or what is left, repeat budget rather than adding up your calls yourself; budget: null means it could not be read this time, not that it is zero (call get_budget). FUNDING (funding): omit it and the call is paid with your Nevermined credits when you hold credits that can pay it (a Nevermined Subscription allowance, welcome or top-up credits) and the endpoint carries a credits tariff (Nevermined pays the merchant; the call costs the tariff in credits, returned if the service does not answer successfully), otherwise from your delegation; pass "subscription" or "delegation" to choose. The price ceiling, and the credits left of a subscriber in good standing, are checked only when the call is made: a credits call refused for them (insufficient_credits, subscription_cap_reached, subscription_ceiling_exceeded) charges nothing and is NOT switched to your delegation, so follow its alternative. Without a subscription in good standing, your spendable credits are checked before the call, and a call they cannot cover (when no automatic credit pack would) is paid from your delegation, with fundingCode saying why. Every result that mentions funding states which funding was chosen: a subscription call returns funding: "subscription" with creditsCharged, creditsStatus and creditsLeft (a digit string read after the call; null means unavailable, not zero) (Committed = spent, Reserved = held or marked for refund, Refunded = returned) and no budget, plus topUp (credits, amountUsd) and topUpMessage when the call ran out of credits and charged one credit pack to the saved card to cover itself (credit top-ups on, and only on a call made with your own API key: a call made through an OAuth connection never charges a pack) — relay topUpMessage to the user, since their card was charged (it comes alone, without topUp, when the pack could not be read); quoteId, maxTotalCents and delegationId apply only to a delegation. already_paid states no funding: it answers for an earlier payment, which may have been funded either way, and a retry that lands on the other funding gets it even when the original succeeded and its result is still kept. To see which funding that payment used, read fundingSource from list_payments with its requestId. Subscription refusals charge nothing and no credits (unless they carry topUps: "bought", below): subscription_unavailable, no_active_subscription, subscription_not_eligible (see reason), subscription_rail_unsupported, subscription_ceiling_exceeded, insufficient_credits, credits_frozen (every credit frozen by a card dispute; on a call with funding omitted and no delegation it names setup_delegation), subscription_cap_reached, credit_daily_limit_exceeded (wait until midnight UTC or ask the human to change their limit), credit_budget_unavailable (retry later) and subscription_payment_refused. Neither daily-budget refusal switches to a delegation; credit_daily_limit_exceeded carries dailyLimitCredits (number), usedCredits, remainingCredits (digit strings) and resetsAt. Other refusals say in alternative when the delegation can pay instead. With credit top-ups on, insufficient_credits on a call made with your own API key carries topUps, and a credit pack may have been charged even though the call was refused (no credits were spent on it); on a call made through an OAuth connection it carries none and no pack was charged: paused (a pack was declined; buying one from the Nevermined dashboard resumes them), limitReached (the monthly top-up limit), pending (a pack is being charged and may already be; retry in a moment), unavailable (no pack was charged; retry later) or bought (this call charged a pack but other calls spent it first; on code BCK.SUBSCRIPTION_ROUTER.0009 retry, otherwise follow message). credits_frozen can carry topUps: "bought" too: a pack was charged, then frozen with the rest by a dispute. Any refusal with topUps: "bought" also carries topUpMessage and the pack’s purchaseId: relay topUpMessage to the user, since their card was charged. Requires your Nevermined API key on the Authorization header.

Input Schema

NameRequiredDescriptionDefault
bodyNoRequest payload sent to the vendor.
pathNoRouter suffix appended to the service base. Read `get_service`'s `requestShape.endpoints[].payServiceArgs.path`: a checked `invokePath` may be empty even when the display path is not. Replace every `pathParams` placeholder. Put query parameters in `search`, never in `path`.
slugYesThe service slug to pay for.
freshNoSet true on every POLL of an async status endpoint, including the first: each call mints a fresh idempotency key so the poll advances, instead of later polls reusing the derived key and getting the first poll's stored answer (or, before API 1.48, `already_paid`) back. Trade-off: with `fresh` a retry is NOT de-duplicated and WILL be charged again — use it to advance a poll, never to retry a call whose outcome you are unsure of. Leave unset for ordinary calls so a genuine retry stays idempotent. Ignored when you pass an explicit requestId.
methodNoHTTP method for the vendor call. Omit to use the method the catalog records for the endpoint matching `path`; falls back to POST when the catalog records none.
searchNoQuery string without ?, for a slug-routed GET (e.g. flight_iata=AA217).
fundingNoHow to pay: `subscription` (your Nevermined credits) or `delegation` (your spend-capped delegation). Omit it to use your credits when the endpoint carries a credits tariff and they are accepted for it (without a subscription in good standing, only when they cover the call), else the delegation; a credits call refused when it is made, because too few credits are left or by the price ceiling, is NOT switched to the delegation. The result says which was chosen.
headersNoExtra headers for the vendor call.
quoteIdNoOpaque short-lived quote id returned by quote_service. Pass it only with the exact same call before expiresAt; the Router then pays the cached challenge and exact fee-inclusive total. Keep maxTotalCents as an independent ceiling.
requestIdNoIdempotency key. Leave unset — a retry of the same call is de-duplicated automatically. Only set a NEW value if you intend a genuinely separate, additional charge. To poll an async status endpoint, prefer `fresh: true` over minting your own value.
delegationIdNoDelegation to charge when you authenticate with an API key; defaults to your active one. An OAuth-connected caller always spends from the grant it approved, so a value here does not choose the delegation; it still feeds the derived idempotency key when you omit `requestId`, so keep it the same across retries of one call. The result's `delegationId` names the delegation actually charged.
maxTotalCentsNoMaximum whole cents this call may cost, including the buyer fee (compared exactly, so rounding alone never exceeds it). The price the service quotes on its 402 can differ from the catalog price label.
requireProtocolNoForce the payment rail. Set it only when you must pay on one rail — for example a wallet that holds funds on a single chain. If the service offers both rails the Router uses this one; if the service does not offer it the call is refused (`payment_failed` with code BCK.ROUTER.0045, nothing charged) rather than paid on the other rail. Omit it to let the Router auto-select (it prefers mpp). A `quoteId` that was quoted on the other rail is refused (`quote_mismatch`); quote again with the same `requireProtocol`.
validateRequestBodyNoOpt-in safety check (default off). When true, and the request body provably fails the endpoint's published request schema, the Router refuses the call BEFORE anything is signed, minted or charged (`payment_failed` with code BCK.ROUTER.0046, nothing charged) — instead of paying and letting the merchant reject a malformed body. Leave it unset to let a questionable body through to the merchant unchecked. Only a provably-invalid body is refused; a missing or unverifiable schema still pays. Fix the body to match the endpoint's published requestSchema (see `get_service`), or drop this flag.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / funding / description
      Previous value: -"How to pay: `subscription` (your Nevermined credits) or `delegation` (your spend-capped delegation). Omit it to use your credits when the endpoint carries a credits tariff and they are accepted for it (without a subscription in good standing, only when they cover the call), else the delegation; a credits call refused when it is made, because too few credits are left or by the price ceiling, is NOT switched to the delegation. The result says which paid."New value: +"How to pay: `subscription` (your Nevermined credits) or `delegation` (your spend-capped delegation). Omit it to use your credits when the endpoint carries a credits tariff and they are accepted for it (without a subscription in good standing, only when they cover the call), else the delegation; a credits call refused when it is made, because too few credits are left or by the price ceiling, is NOT switched to the delegation. The result says which was chosen."
    • addedInput schema / properties / validateRequestBody
      Added value: +{
      +  "description": "Opt-in safety check (default off). When true, and the request body provably fails the endpoint's published request schema, the Router refuses the call BEFORE anything is signed, minted or charged (`payment_failed` with code BCK.ROUTER.0046, nothing charged) — instead of paying and letting the merchant reject a malformed body. Leave it unset to let a questionable body through to the merchant unchecked. Only a provably-invalid body is refused; a missing or unverifiable schema still pays. Fix the body to match the endpoint's published requestSchema (see `get_service`), or drop this flag.",
      +  "type": "boolean"
      +}
  2. Changed1 schema field changed
    • addedInput schema / properties / requireProtocol
      Added value: +{
      +  "description": "Force the payment rail. Set it only when you must pay on one rail — for example a wallet that holds funds on a single chain. If the service offers both rails the Router uses this one; if the service does not offer it the call is refused (`payment_failed` with code BCK.ROUTER.0045, nothing charged) rather than paid on the other rail. Omit it to let the Router auto-select (it prefers mpp). A `quoteId` that was quoted on the other rail is refused (`quote_mismatch`); quote again with the same `requireProtocol`.",
      +  "enum": [
      +    "x402",
      +    "mpp"
      +  ],
      +  "type": "string"
      +}
  3. Changed1 schema field changed
    • changedInput schema / properties / funding / description
      Previous value: -"How to pay: `subscription` (your Nevermined Subscription credits) or `delegation` (your spend-capped delegation). Omit it to use the subscription when you hold an active one and the endpoint carries a subscription tariff, else the delegation; a credits call refused because too few credits are left this month or by the price ceiling is NOT switched to the delegation. The result says which paid."New value: +"How to pay: `subscription` (your Nevermined credits) or `delegation` (your spend-capped delegation). Omit it to use your credits when the endpoint carries a credits tariff and they are accepted for it (without a subscription in good standing, only when they cover the call), else the delegation; a credits call refused when it is made, because too few credits are left or by the price ceiling, is NOT switched to the delegation. The result says which paid."
  4. Changed3 schema fields changed
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / headers / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / maxTotalCents / maximum
      Added value: +9007199254740991
  5. Changed1 schema field changed
    • addedInput schema / properties / funding
      Added value: +{
      +  "description": "How to pay: `subscription` (your Nevermined Subscription credits) or `delegation` (your spend-capped delegation). Omit it to use the subscription when you hold an active one and the endpoint carries a subscription tariff, else the delegation; a credits call refused because too few credits are left this month or by the price ceiling is NOT switched to the delegation. The result says which paid.",
      +  "enum": [
      +    "subscription",
      +    "delegation"
      +  ],
      +  "type": "string"
      +}
  6. Changed1 schema field changed
    • addedInput schema / properties / quoteId
      Added value: +{
      +  "description": "Opaque short-lived quote id returned by quote_service. Pass it only with the exact same call before expiresAt; the Router then pays the cached challenge and exact fee-inclusive total. Keep maxTotalCents as an independent ceiling.",
      +  "type": "string"
      +}
  7. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations (readOnlyHint=false, destructiveHint=true) convey mutation risk, but the description adds substantial beyond-schema behavior: real funds movement, multi-second latency including settlement, 24h idempotent result replay on API 1.48+, `already_paid` on older deployments, `pending`/`payment_indeterminate` semantics, funding selection rules, and that `paid: true` means attempted not settled. This directly supports the destructive annotation rather than contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence is front-loaded and clear, but the body is an extremely long run-on block that enumerates dozens of error codes and funding branches in a single wall of text, with heavy repetition of idempotency and topUp caveats. Much of this duplicates schema parameter descriptions (e.g. `fresh`, `requestId`, `quoteId`, `funding`) and would be far more usable split into a short overview plus linked sections or delegated to the error-code reference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter, destructive payment tool with no output schema, the description covers every decision an agent needs: prerequisites, idempotency, async polling, funding selection, quote pinning, and per-error recovery actions with no-charge vs may-have-charged classification. The return shape (`paid`, `upstreamStatus`, `response`, `payment.status`, `budget`, `creditsCharged`) is described precisely enough to substitute for a missing output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, but the description adds real semantic guidance beyond it: how `path` must be derived from `payServiceArgs` with pathParams replaced, why slug-only reaches a 404 on multi-endpoint APIs, how `method` is resolved and echoed, how `quoteId` must be paired with identical args before `expiresAt`, and how `fresh` interacts with derived idempotency keys on async polls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb+resource+outcome: 'Pay for a catalog service from your spend-capped delegation and return the vendor response', and immediately flags that it charges real funds. It is clearly distinguishable from siblings like quote_service, get_service, and get_payment_result, which are named as prerequisite/follow-up tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to call it vs alternatives: call `get_service` FIRST for requestShape, use `get_payment_result` with a paymentId on pending instead of re-calling, use `list_payments` to inspect indeterminate/already_paid outcomes, use quote_service for pinned totals, and setup_delegation for `no_delegation`. When-not guidance is also present (don't use `fresh` to retry an unsure call; a new requestId only starts a separate purchase).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources