Skip to content
LogoLogo

Nava Gateway API reference

Developer Preview

The preview package is named @navalabs/x402-guardian. It exposes these import paths:

import { verifyPayment, withGuardian } from '@navalabs/x402-guardian';
import { createResourceGate } from '@navalabs/x402-guardian/resource';
import { paymentGate } from '@navalabs/x402-guardian/fastify';
import { fetchVerificationRequirements } from '@navalabs/x402-guardian/pricing';

verifyPayment

verifyPayment(
  input: VerifyPaymentInput,
  config: GuardianConfig,
  options?: PollOptions,
): Promise<GuardianResult>

input contains raw paymentPayload and paymentRequirements. The function builds a preview PaymentAction, uses authorization.from as the Guardian escrowAddress, submits the action, and polls for a terminal verdict. It does not settle.

PollOptions accepts intervalMs and maxAttempts; defaults are 1,000 ms and 20 attempts. Guardian polling timeouts and request/response failures are normalized to a non-approved result. Invalid payment inputs can fail while the action is being built, so callers must still catch exceptions and fail closed.

withGuardian

withGuardian(
  baseVerify: VerifyFn,
  config: GuardianConfig,
  options?: PollOptions,
): VerifyFn

VerifyFn receives (paymentPayload, paymentRequirements) and returns an x402 verify result. The wrapper preserves an invalid base result without calling Guardian. A valid base result remains valid only when Guardian approves. The returned object can include guardianStatus and guardianReason.

paymentGate

paymentGate<Ctx>(config: FastifyGateConfig<Ctx>): FastifyPreHandler

Exported from @navalabs/x402-guardian/fastify. It delegates to createResourceGate, reading request.headers['x-payment']. A settled result adds X-PAYMENT-RESPONSE, attaches { settlement, guardian } to request.x402, and continues. Other results are sent immediately with their status/body.

The config adds an optional ctx(request) mapper to ResourceGateConfig. Important resource fields are network, optional asset, payTo, price, optional resource metadata, facilitatorUrl, optional facilitatorKey, and guardian: "off" | { advertise?: "required" | "optional"; fee?: boolean }.

createResourceGate

createResourceGate<Ctx>(config: ResourceGateConfig<Ctx>): {
  requirements(ctx: Ctx): Promise<PaymentRequirements>;
  verificationRequirements(
    merchant: PaymentRequirements,
  ): Promise<PaymentRequirements | null>;
  handle(input: { xPayment?: string; ctx: Ctx }): Promise<GateResult>;
}

Exported from @navalabs/x402-guardian/resource. handle returns one of:

kindStatusMeaning
payment-required402No payment was supplied; body contains accepts and optional verification.
rejected402x402 or Guardian verification did not approve; merchant settlement did not run.
settled200Merchant settlement succeeded; includes settlement data and a base64 payment-response header.
error400, 502, or dependency-specific statusThe header was malformed or a required preview dependency failed.

fetchVerificationRequirements

fetchVerificationRequirements(
  pricingUrl: string,
  resource: PaymentRequirements,
  options?: { timeoutMs?: number },
): Promise<PaymentRequirements | null>

Exported from @navalabs/x402-guardian/pricing. It posts { resource } to the pricing service and returns that service's requirements or null. The package does not compute a verification price. Non-2xx responses throw; the shared JSON transport rejects redirects and oversized responses.

Types

GuardianConfig

FieldTypeRequiredBehavior
baseUrlstringYesGuardian service base URL. A trailing slash is removed.
apiKeystringYesSensitive fallback Guardian key when the payload has no payer key.
timeoutMsnumberNoDeclared and honored by direct GuardianClient construction. The high-level helpers fail to forward it; see the limitation below.
allowPromptOverridebooleanNoAllows unsigned arbiterUserPrompt; default behavior derives the prompt from the payment action.

GuardianResult

FieldTypeMeaning
approvedbooleantrue only when the terminal verdict outcome is approved.
statusapproved | rejected | timeout | errorNormalized integration result.
reasonstring, optionalHuman-readable verdict or failure reason.
verdictGuardianVerdict, optionalPresent for terminal verdicts; read its outcome as authoritative and pass unknown reasonCode values through.

GuardianVerdict.outcome is pending, approved, or rejected. Its required preview subset is outcome, reasonCode, and humanReason; additional optional fields include checks, evidence, policy version, USD notional, and timestamp.

PaymentAction

FieldTypeRequiredSource
protocolliteral paymentYesPreview adapter constant; final venue key unresolved.
railliteral x402YesPreview rail.
chainIdnumberYes8453 for Base or 84532 for Base Sepolia.
payTostringYespaymentPayload.payload.authorization.to.
assetstringYespaymentRequirements.asset.
amountstringYesAuthorization value in token base units.
resourcestringNopaymentRequirements.resource.

This is a field-copy adapter, not a final canonical decode. Normalized-versus-raw input and the payment field contract remain unresolved.

Preview facilitator endpoints

When FACILITATOR_API_KEY is configured, /verify, /settle, and /verification/quote require x-facilitator-key. The checked-in preview server otherwise leaves them open for development. /health is not protected by that key in the Developer Preview.

POST /verify — Developer Preview

Developer Preview endpoint table

ItemContract
Request{ paymentPayload, paymentRequirements, verificationRequirements? }
Success status200; inspect isValid, not HTTP status alone.
Valid body{ isValid: true, payer?, guardianStatus?, guardianReason?, feeTxHash? }
Invalid body{ isValid: false, invalidReason, payer?, guardianStatus?, guardianReason?, feeTxHash?, feeError? }
Other failuresGuardian handler failure can return a generic 500 error.

The endpoint pins network/asset, checks an optional minimum amount, runs x402 verification, conditionally runs Guardian according to GUARDIAN_MODE, and, when Guardian applies, settles a quoted verification fee on a terminal verdict. It never settles the merchant payment.

POST /settle — Developer Preview

Developer Preview endpoint table

ItemContract
Request{ paymentPayload, paymentRequirements }
Logical success200 with { success: true, txHash, network, payer? }.
Logical failureUsually 200 with { success: false, errorReason, network, payer? }.
Exceptional failure500 with { success: false, errorReason, network }.

When Guardian applies, the endpoint requires an unexpired approval for the exact payer, payee, amount, asset, network, and signed nonce, then consumes it before merchant settlement. Consumption is atomic only with the Redis store's GETDEL. The default memory store performs a non-atomic async read/delete, so concurrent calls can both reach broadcast. EIP-3009 prevents two successful token transfers, but a duplicate broadcast can still cost facilitator gas.

The approval is already gone when merchant broadcast begins. After a logical settlement failure, exceptional 500, or resource-gate 502, do not blindly retry /settle. Reconcile an uncertain transaction and run /verify again for the exact payment; when the previous verification fee authorization was consumed, obtain a fresh one.

POST /verification/quote — Developer Preview

Developer Preview endpoint table

ItemContract
Request{ resource: PaymentRequirements }
200{ requirements: PaymentRequirements | null }; null when pricing is not configured or no fee applies.
400Missing resource requirement.
502Pricing service unavailable; raw upstream detail is not reflected.

This endpoint is a pass-through. The Nava Gateway preview does not calculate the verification fee.

GET /health — Developer Preview

Developer Preview endpoint table

ItemContract
Default 200{ "status": "ok" } with no RPC read.
Detailed 200When explicitly enabled, can include network, chain, scheme, asset, facilitator address/balances, and Guardian URL; balance reads are cached.

The minimal response is the safer disclosure boundary. These endpoint shapes describe only the Developer Preview server and do not establish a hosted or production Gateway service.