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,
): VerifyFnVerifyFn 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>): FastifyPreHandlerExported 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:
kind | Status | Meaning |
|---|---|---|
payment-required | 402 | No payment was supplied; body contains accepts and optional verification. |
rejected | 402 | x402 or Guardian verification did not approve; merchant settlement did not run. |
settled | 200 | Merchant settlement succeeded; includes settlement data and a base64 payment-response header. |
error | 400, 502, or dependency-specific status | The 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
| Field | Type | Required | Behavior |
|---|---|---|---|
baseUrl | string | Yes | Guardian service base URL. A trailing slash is removed. |
apiKey | string | Yes | Sensitive fallback Guardian key when the payload has no payer key. |
timeoutMs | number | No | Declared and honored by direct GuardianClient construction. The high-level helpers fail to forward it; see the limitation below. |
allowPromptOverride | boolean | No | Allows unsigned arbiterUserPrompt; default behavior derives the prompt from the payment action. |
GuardianResult
| Field | Type | Meaning |
|---|---|---|
approved | boolean | true only when the terminal verdict outcome is approved. |
status | approved | rejected | timeout | error | Normalized integration result. |
reason | string, optional | Human-readable verdict or failure reason. |
verdict | GuardianVerdict, optional | Present 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
| Field | Type | Required | Source |
|---|---|---|---|
protocol | literal payment | Yes | Preview adapter constant; final venue key unresolved. |
rail | literal x402 | Yes | Preview rail. |
chainId | number | Yes | 8453 for Base or 84532 for Base Sepolia. |
payTo | string | Yes | paymentPayload.payload.authorization.to. |
asset | string | Yes | paymentRequirements.asset. |
amount | string | Yes | Authorization value in token base units. |
resource | string | No | paymentRequirements.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
| Item | Contract |
|---|---|
| Request | { paymentPayload, paymentRequirements, verificationRequirements? } |
| Success status | 200; 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 failures | Guardian 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
| Item | Contract |
|---|---|
| Request | { paymentPayload, paymentRequirements } |
| Logical success | 200 with { success: true, txHash, network, payer? }. |
| Logical failure | Usually 200 with { success: false, errorReason, network, payer? }. |
| Exceptional failure | 500 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
| Item | Contract |
|---|---|
| Request | { resource: PaymentRequirements } |
200 | { requirements: PaymentRequirements | null }; null when pricing is not configured or no fee applies. |
400 | Missing resource requirement. |
502 | Pricing 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
| Item | Contract |
|---|---|
Default 200 | { "status": "ok" } with no RPC read. |
Detailed 200 | When 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.