Owners sign with the wallet they already have. The Agent API picks the signing standard and returns it in intent.standard. This page explains each standard and what the owner agrees to. You only need it to debug a wallet integration or explain a prompt to owners: Owner Signing has the frontend code.
At a glance
  • NEAR owners: nep366 (a delegate action the API relays on-chain) or nep413 (a signed message).
  • EVM owners: eip712 typed data, shown field by field in the wallet.
  • Passkey owners: webauthn, a Face ID, fingerprint or PIN prompt.
  • One rule: the wallet signs intent.payload exactly as returned. You never build these messages yourself.

Two kinds of owner requests

Every owner intent is one of two kinds. The kind decides the standard.

Wallet requests (on-chain)

agent_create, agent_freeze, agent_unfreeze, agent_delete, and a policy_update that changes the wallet’s rules (actions, assets, limits, approval, max_actions_per_hour).The owner signs a NEAR call that the API sends to the chain and pays gas for. It installs, changes or deletes the policy the agent’s wallet enforces. Window: 600 s.

Consent messages (off-chain)

Every other intent: grant_issue, grant_revoke, execution_cancel, agent_archive, agent_restore, approval_vote, and a policy_update that changes only destinations, budget, timelock_ms or schedule.The owner signs a message that the Agent API checks. Nothing is sent to the chain, so there’s no gas. Window: about 290 s (passkey about 270 s).
For a policy_update, the API decides which kind it is from what changed. A NEAR owner can get either nep366 or nep413, so choose the wallet call from intent.standard.

Rules for every standard

  • Sign the payload as it is. Don’t rebuild, hash, reorder or re-encode it. The API compares what comes back with what it sent, and refuses any difference with intent_payload_mismatch.
  • Sign with the owner’s key. A NEAR owner’s key must be a full-access key. A signature from any other key fails with signer_mismatch (signed messages and passkeys), policy_delegate_owner_mismatch (NEAR delegate actions), owner_key_not_full_access (the key isn’t full access), or a signature error such as owner_proof_invalid. Owner Signing shows which flow gives which.
  • Use the standard you were given. Signing with another one fails with intent_standard_mismatch.
  • Sign before expires_at. Every intent from generate-intent has a deadline: about 290 s for consent messages (about 270 s for passkeys), 600 s for wallet requests. After it, you get intent_expired: generate a new one. Timestamps the API stamps into EVM and passkey messages are set 30 s in the past, to absorb clock skew between servers and devices.
  • Each intent works once. A nonce can’t be reused. Submitting the same signature again is safe and returns the same result.
  • Encodings. The API accepts NEAR signatures as base58, base64 or hex, and normalizes EVM recovery IDs and WebAuthn DER signatures.

NEAR owners

The owner signs a NEAR transaction without sending it. The API, as the relayer, sends it and pays the gas (NEP-366). Window: 600 s. The owner’s key must still be able to execute the delegate when it is relayed, or you get policy_delegate_expired.intent.payload has receiverId and a list of one or two actions. Each action is a FunctionCall with params: methodName, args, gas and deposit. The wallet signs it with signDelegateActions, and you return the result as signed_delegate.The delegate is signed by the owner’s account and key from agent_create, so the policy change is made by the owner’s own account. Another account or key is refused with policy_delegate_owner_mismatch. For agent_delete, the single action is the wallet’s delete_wallet_policy call. For a policy update, the arguments include a hash of the complete policy, so the signature covers every rule, including the ones the API enforces itself (destinations, budget, timelock_ms, schedule).

EVM owners

EVM owners sign EIP-712 typed data, so the wallet shows the owner every field before they sign. Both message types use the same domain:
The domain has no chainId, so the owner can sign on any EVM network their wallet is connected to.
A request for the owner’s 0s account on NEAR. The account checks the owner’s signature and runs the request. See Owner Accounts.
The wallet signs with eth_signTypedData_v4, for example walletClient.signTypedData in viem. Return the 65-byte signature, 0x-prefixed, as signature. The API checks that it comes from the owner’s public_key.

Passkey owners

Passkey owners sign with WebAuthn, the standard behind Face ID, Touch ID and security keys. intent.payload is a ready-to-use request for the browser: Pass it to navigator.credentials.get, or to startAuthentication in @simplewebauthn/browser, and return the result as credential. What the challenge is a hash of depends on the kind of request:
The challenge is the SHA3-256 hash of a wallet request for the owner’s 0s account: the NEAR network, the account, a one-time nonce, a validity window and the NEAR calls to make. The account checks the passkey signature and runs the request.The window is 600 s from a creation time set 30 s in the past, so about 570 s remain.

Consent messages are canonical JSON, the same for every owner type, except approval_vote (below). They name the owner, the tenant and the agent, and carry a single-use nonce and a deadline. The rest depends on the intent: agent_delete is not a consent message. It is a wallet request: the owner signs the agent wallet’s delete_wallet_policy call as a nep366 delegate action, an EIP-712 WalletMessage or a WebAuthn assertion over the wallet request hash. preview.deletion shows what would be lost. See Deleting an agent. Show preview next to the wallet prompt so the owner sees this in plain language.