A three-minute read: what you set up, what the owner signs, what you can build, and what is checked before an agent moves funds.

Set up in three steps

1

Get a partner API key

Create one in the Partner Dashboard. It lives on your backend, as NEAR_INTENTS_AGENT_API_KEY, and works for all of your agents. See Partner API Key.
2

The owner signs twice

Your backend generates two requests and the owner’s wallet signs each one: agent_create sets the agent’s rules (its policy), and grant_issue gives your backend a grant token. See Owner Signing.
3

Your backend acts

Call swap, transfer, withdraw and the other actions with the key and the grant token. The owner doesn’t sign these, and every one is checked against the policy.

What you can build

Every row is one agent with one policy. Run as many assistants or bots against it as you like, each with its own grant.

The pieces

Policy decides what. Grant decides who. An agent has one policy and many grants. The policy and the USD budget belong to the agent, so every grant follows them and shares one budget. Changing a rule never means issuing new grants, and issuing or revoking a grant never changes a rule.

Three credentials

Each call uses one or more of these. None of them can replace another.

Partner API key

naa_…, sent as X-API-Key. Kept on your backend. Says which partner is calling. One key works for all of your agents.

Grant token

ngt_…, sent as X-Grant-Token. Created and kept by your backend. Says which owner-signed grant an action runs under.

Owner signature

Made by the owner’s wallet. Proves the owner agrees to an action, such as creating the agent, changing the policy or giving a grant.
Never put the partner API key or a grant token in a browser, a mobile app or an AI model’s prompt.

Agents

An agent is one account with its own assets and its own rules. Each agent has:
  • One owner. A NEAR account or a passkey. EVM wallets work only where enabled: GET /v1/network lists the owner types you can use in supported_owner_types, and EVM isn’t enabled by default. One owner can have many agents.
  • One wallet with its own NEAR Intents account, holding a public balance and a confidential balance. Agents never share balances or history.
  • One policy. The rules the owner signed.
  • One USD budget, part of the policy and shared by every grant on the agent.
NEAR owners use their own NEAR account. Passkey and EVM owners don’t need one: the API derives a NEAR account for them from their public key, and that account controls the agent’s wallet rules on-chain. See Owner Accounts.

Lifecycle

Agent lifecycle in five steps: create with the name, owner and complete policy; the owner signs the rules; your backend makes a grant token and the owner signs who may act and until when; your backend acts with the grant token; the owner manages the policy, grants and freeze Agent lifecycle in five steps: create with the name, owner and complete policy; the owner signs the rules; your backend makes a grant token and the owner signs who may act and until when; your backend acts with the grant token; the owner manages the policy, grants and freeze
1

Create

Your backend calls generate-intent with type: "agent_create", a name, the owner’s public identity and the complete first policy. The API returns one request for the owner to sign. The agent is PENDING.
2

Owner signs the rules (signature 1)

This signature links the agent to the owner and installs the policy. The API pays the gas. The agent becomes ACTIVE once the policy is confirmed on-chain and the wallet reads it back.
3

Owner grants access (signature 2)

Your backend creates a grant token and sends only its fingerprint. The owner signs a grant_issue with a label and an expiry. The grant names who may act and until when. What that grantee may do is the policy. After this, actions need no owner signature. Each extra grant is one more signature.
4

Your backend acts

Your backend calls swap, withdraw, transfer, shield, unshield and the other actions with your partner API key and the grant token. The owner doesn’t sign these.
5

Owner manages

Changing the policy, freezing or unfreezing, revoking a grant, cancelling a queued action, archiving and deleting each take one owner signature.
Owners can’t change their key, and lost wallets can’t be recovered. If the owner loses access to their wallet, nobody can change the agent’s rules, issue new grants or delete it, including you and the Agent API.

Two kinds of requests

For anything the owner must agree to. Every owner intent uses the same four calls:
  1. POST /v1/generate-intent: get the exact payload the owner must sign, plus a readable preview.
  2. The owner’s wallet signs intent.payload unchanged.
  3. POST /v1/submit-intent: send the wallet’s output back.
  4. GET /v1/status?correlation_id=…&wait_ms=30000: wait for the result.
Types: agent_create, policy_update, agent_freeze, agent_unfreeze, grant_issue, grant_revoke, execution_cancel, agent_archive, agent_restore, agent_delete, approval_vote. See the full list.

The policy

The policy is what the agent may do. The owner signs the complete policy when creating the agent and again for every change. It has these parts: The timelock, the schedule and the budget cover money actions: swaps, withdrawals and transfers. They don’t apply to deposits. The budget doesn’t count shield and unshield either. Native requests skip all three, and destinations and owner_approval too. Each budget cap’s periods start when the applied policy turns it on, so a daily cap turned on at 05:00 resets in full at 05:00 each day. resets_at says when. Moving funds to your own account on another chain or venue, such as your Hyperliquid or Polymarket address, counts like any withdrawal. A deposit back does not credit it. Two layers enforce the policy. The Agent API enforces destinations, budget, timelock_ms and schedule, and counts the per-asset limits and max_actions_per_hour before anything reaches the wallet. The agent’s wallet enforces the rest. Neither layer overrides the other, and none adds allowance to another: a bigger USD budget never lifts a per-asset limit. Changing the policy is one owner signature over the complete policy. Changes to only destinations, budget, timelock_ms or schedule apply at once, with no transaction. Other changes are written on-chain, and actions wait with policy_not_ready until the wallet reads them back. Policy changes have a 10-minute cooldown, except a freeze. An unfreeze has its own 10-minute cooldown (agent_unfreeze_throttled). See Policies & Limits for each setting in detail.

Grants

A grant says who may act for the agent: one grant token, until it expires or is revoked. It carries no permissions of its own. Everything the grantee may do comes from the agent’s policy. Your backend creates the token and the owner signs only its SHA-256 fingerprint, with a label and an expiry of at most 365 days. Create one grant per user session, assistant or bot: an agent holds up to 50, and revoking one never touches another. All grants share the agent’s one policy and one USD budget. See Grants. Owner-only powers can’t be delegated. A grant can run money actions, but only the owner’s signature changes the policy, issues or revokes grants, freezes, archives or deletes the agent.

The checks every action passes

Before an action runs, it passes these checks in order. Each check stands on its own: only a change to the layer that refused it lifts the refusal. An agent action passes five checks in order: grant, policy rules (action, destination and schedule), timelock, USD budget and wallet policy, then runs on NEAR Intents. A failed check stops it with agent_grant_required, policy_action_denied, policy_destination_denied, policy_schedule_denied, spend_budget_exceeded or policy_denied. An agent action passes five checks in order: grant, policy rules (action, destination and schedule), timelock, USD budget and wallet policy, then runs on NEAR Intents. A failed check stops it with agent_grant_required, policy_action_denied, policy_destination_denied, policy_schedule_denied, spend_budget_exceeded or policy_denied.
1

Grant

Is there a live grant for this agent? A missing, expired, revoked or unknown token returns agent_grant_required.
2

Policy rules

Is the action turned on, is the destination allowed and is the schedule open? If not: policy_action_denied, policy_destination_denied or policy_schedule_denied.
3

Timelock

If the policy sets timelock_ms, the action waits as QUEUED and the owner can cancel it. When it’s released, the schedule is checked again.
4

USD budget

Is there room left in the daily, weekly and monthly caps? If not: spend_budget_exceeded. This is decided when the action dispatches, so a queued action counts when it runs, not when it was queued.
5

Wallet policy

The API counts the asset’s hourly, daily and monthly limits and the hourly action cap when the action dispatches, shield and unshield included. If one is used up: policy_limit_exceeded or policy_action_limit_exceeded. The agent’s wallet then checks the asset and its limits again. If its rules refuse: policy_denied. If the owner turned on approval, the action waits as PENDING_APPROVAL until the vote.
Two conditions apply before any of these, to every action:
  • policy_not_ready (409): the latest policy revision isn’t APPLIED yet.
  • wallet_frozen (409): the owner froze the agent. Only an agent_unfreeze intent resumes it.
A swap quote or withdrawal preview (dry: true) is never refused by the account’s rules (action, destination, assets, schedule, USD budget, per-asset limits) or by the balance (insufficient_balance). Each one the live request would fail comes back in warnings under the code that request would get, so you can see a refusal coming. An asset GET /v1/tokens does not list (unsupported_token) or an invalid recipient (invalid_address) refuses the quote itself with 400, before any provider call. A quote without such a warning is a snapshot, not a guarantee: other work can use the budget first. An archived, deleted or frozen account gets no quote: it is refused with the code the live request gets (agent_archived, agent_deleted, wallet_frozen). Only one money action runs per agent wallet at a time. An overlapping request is refused with wallet_busy before anything is sent. Retry it with a new Idempotency-Key once the first one finishes. Fix the layer that refused: every error names it in layer. Ask the owner to change the policy for policy and budget refusals, fund the agent or send less for balance, and fix the request for request. For agent_grant_required, check the token or issue a new grant. A provider refusal with meta.retryable is worth the same key again later. A budget or limit refusal on an execution that runs now leaves no operation and charges nothing; a timelocked one released over budget ends FAILED. See Status & Errors for how to read results.

Deposits

POST /v1/agents/{agent_id}/deposit returns a NEAR Intents 1Click deposit address that credits the agent from another chain. It needs only your partner API key and an Idempotency-Key: no grant and no owner signature. A failed or late deposit refunds to the agent’s own balance. See Funding.

Gas

Some owner requests are written to the NEAR blockchain, so the agent’s wallet can enforce them on-chain. Each one is a NEAR transaction that needs gas and a small storage deposit. The Agent API pays for both. Neither you nor the owner needs NEAR for gas. Everything else the owner signs (grants, revoking, cancelling, archiving and approval votes) needs no blockchain transaction and no gas. Agent actions run inside NEAR Intents, which needs no gas, so you never fund an agent with gas. If the service can’t pay gas for a moment, sponsor_balance_insufficient or sponsor_busy (both 503) come back. The owner’s request stays signable, so retry the same request shortly.
Policy changes have a per-agent cooldown, 5 minutes by default. A freeze skips it, so the owner can always stop an agent in an emergency. An unfreeze has its own cooldown (agent_unfreeze_throttled).

Next steps

Quickstart

Run the whole flow in about 30 minutes.

Policies & Limits

Every policy rule in detail.