A limit order rests at a price the agent picks, on the agent’s NEAR Intents balance, until it fills, is cancelled or reaches its deadline. Your backend places it with your partner API key and a grant token, like any other execution. The owner doesn’t sign it: the agent’s policy decides whether it may be placed and how far from the market its price may be.
At a glance
  • Place: POST /v1/agents/{agent_id}/limit-orders with X-API-Key, X-Grant-Token and an Idempotency-Key. It answers 202 with a status and a correlation_id (op_…).
  • SUCCESS means resting, not filled. The order is funded in full and on the book. details.order_id names it. Read its fills with GET …/limit-orders/{order_id}.
  • Policy: limit_order in actions, and limit_order.max_deviation_bps (0 to 300, default 100) bounds the price against the market. destinations does not apply.
  • Cancel: with a grant only. It works while the agent is frozen or after the policy drops limit_order, and what is unfilled is refunded. The USD budget charge is not given back.
  • Preview: dry: true needs only the API key.
These are the Agent API’s limit orders: an agent places them from its own NEAR Intents balance, under its owner’s policy. They are not the 1Click Swap API’s Limit Orders, which your app creates with 1Click credentials and funds from a deposit address as confidential 1Click swaps. Agent API orders rest on the agent’s confidential balance.

Place an order

Every snippet on this page assumes the setup from Executions: an api client, an assistant client for one grant, and an agentId. The order is funded in full when it is placed:
  • A sell spends quantity of base_asset. A full fill delivers quantity × price of quote_asset.
  • A buy spends the quote_asset that quantity costs at price, rounded up, and a full fill delivers quantity of base_asset.
Selling 1 wNEAR (24 decimals) at "5.2" USDT (6 decimals) spends 1000000000000000000000000 wNEAR and delivers up to 5200000 USDT. Buying 1 wNEAR at the same price spends 5200000 USDT and delivers up to 1000000000000000000000000 wNEAR.
Follow correlation_id with GET /v1/status like any execution. When it reads SUCCESS, the order is funded and resting, and details.order_id is its id. The status also echoes the request that was admitted, in details.request: side, quantity, price, deadline and confidential, with origin_asset and amount as what the order spends and destination_asset as what it receives. The usual execution rules apply. The Idempotency-Key is required, and a retry with the same key and body returns the same operation, and a replay of an admitted order is not judged again. A timelock holds the order as QUEUED, and owner_approval holds it as PENDING_APPROVAL. An UNCERTAIN order is never resent under a new key; recover it with type: "limit_order" and its original body, or keep polling.

Minimum

An order must be worth at least 0.1 USD, measured on what it spends. A smaller one is refused with amount_too_low (400, source.pointer /quantity) before anything is recorded or charged. For a sell, meta.min_amount is the smallest quantity that is worth 0.1 USD. A buy’s refusal names no minimum, because quantity is not the asset it spends. If the asset the order spends has no fresh USD price, the API cannot value the order and skips this check. A route can have its own minimum too, which the provider reports as amount_too_low with 409.

Price bound

The price is judged against the market so that a mistyped price cannot sell far below it or buy far above it. The market price is the base asset’s USD price divided by the quote asset’s, from the same prices as GET /v1/tokens.
  • A sell may be priced at most limit_order.max_deviation_bps basis points below the market.
  • A buy may be priced at most that far above the market.
  • A better price than the market is never limited. A sell above the market, or a buy below it, rests until the market reaches it.
max_deviation_bps is the owner’s choice, from 0 to 300. When the policy has no limit_order rule, it is 100, so a sell may be priced up to 1% below the market. Only the owner changes it, with a policy_update: see Policies & Limits. An order outside the bound is refused with policy_price_deviation_exceeded (403, source.pointer /price), and detail states the market price it was judged against. An order whose base or quote asset has no fresh USD price (updated within 10 minutes) is refused with market_price_unavailable (503, source.pointer /base_asset or /quote_asset): the API will not skip the check. Neither refusal records or charges anything. Retry market_price_unavailable once GET /v1/tokens prices both assets. The price is judged when the order is placed, and again when a timelock or the owner’s approval releases it. Both checks use the market price at that moment. If a price is briefly unavailable when a timelock releases an order, the API tries the order again later instead of failing it.

Preview an order

dry: true returns 200 with a preview and places nothing. It needs only your partner API key: no grant and no Idempotency-Key. It makes no provider call, so it is not a custody operation.
The answer has the shape of any quote, with type: "limit_order". Its quote is the API’s own { side, spend_asset, spend_amount, receive_asset, min_amount_out, note }: what the order spends and the least a full fill delivers, before 1Click’s fee. spend is the USD value the budget would count and the budget before this order. warnings lists each rule the live order would fail, under the code it would get: the codes in Account rules in a quote, plus amount_too_low, policy_price_deviation_exceeded and market_price_unavailable. A preview is a snapshot, not a reservation. An archived, deleted or frozen agent gets none.

Follow an order

SUCCESS ends the placement, not the order. After that the order rests until it fills, is cancelled or reaches its deadline. What it spent has left the balance; fills and the unfilled remainder return to the balance that funded it. GET /v1/agents/{agent_id}/limit-orders/{order_id} reads the order live from 1Click, in 1Click’s own snake_case fields: Any other field 1Click sends passes through unrenamed. An id that is not this agent’s is limit_order_not_found (404). GET /v1/agents/{agent_id}/limit-orders lists the agent’s orders, newest first, as { "data": [ … ] }. Pass open=true for orders still resting. It pages with limit (1 to 100) and offset, not with a cursor, and has no next_cursor: raise offset until a page is empty. The list does not refresh an order’s status, so read one order for its live state.
Both reads need only your API key and are not custody operations, so they count toward no quota.

Cancel an order

POST /v1/agents/{agent_id}/limit-orders/{order_id}/cancel cancels a resting order, and what is unfilled is refunded to the agent’s balance. It needs a grant and no Idempotency-Key.
  • It waits for nothing: no timelock, schedule or owner approval, and it spends no budget.
  • It works while the agent is frozen and after the policy stops allowing limit_order. The owner’s rules never trap an order. Only an archived or deleted agent refuses it.
  • The USD budget charged when the order was placed is not given back, and a refund does not credit it.
  • A cancel is judged against a live grant and API key when it is sent. If the grant is revoked while a cancel is on its way, the revocation lists it in committed_cancellations: it may still reach the provider, so read the order.
  • The answer is the order as the provider reports it, with every field optional, or {} when it reports none. Read the order for its state.
POST /v1/agents/{agent_id}/limit-orders/cancel-all cancels up to 50 orders a call. Repeat it until complete is true. It answers { known, cancelled, failed, remaining, complete }.
A cancel counts as one custody operation and can be refused with wallet_busy (409) while another money action runs, or with provider_limit_reached (429). The refund has landed once the order’s payout is final: poll GET …/limit-orders/{order_id} until is_payout_status_final is true.

What the policy and budget do

A limit order runs through the same rules as a swap on the asset it spends: Changing only limit_order.max_deviation_bps needs no blockchain transaction, like destinations, budget, timelock_ms and schedule. Adding or removing limit_order in actions changes the wallet’s own rules and is written on-chain. See Policies & Limits.

Confidential orders

Orders fund from the confidential balance, and fills and refunds return there. The policy needs confidential: true as well as limit_order in actions. An order never falls back to the public balance. confidential: false is refused with public_balance_exit_only, live and dry. An order already resting on the public balance keeps running: its status, fills and cancel still work.

Freeze and delete

OutLayer leaves a resting order running when an agent is frozen or its policy drops limit_order, and its fills and refunds land in the account regardless. So the API cancels the agent’s resting orders in both cases. This is best effort and retried until it finishes, and it never blocks the freeze or the policy change. An agent with resting orders cannot be deleted. agent_delete is refused with limit_orders_open (409) while any order is not payout-final, and preview.deletion.open_limit_orders counts them. Freeze the agent, which cancels them, wait for the cancellations to pay out, then submit the deletion again. The check runs before deletion_assets_remaining, because a cancel refunds into the balance. See Deleting an agent.

Fee and quotas

Every order pays 1Click’s own fee, shown as app_fees on the order (currently 20 basis points). It is 1Click’s fee, not the API’s and not the wallet provider’s. Placements and cancels count toward the wallet’s 1,000 custody operations per rolling 24 hours. Previews, quotes and reads do not. See Network & Quotas.

With the SDK

SDK 0.8.1 adds five methods. placeLimitOrder gets the 150 s settlement timeout and creates the Idempotency-Key when you omit it, returned as idempotencyKey. With dry: true it returns the quote and needs no grant or key. listLimitOrders returns { data }, not an array. cancelLimitOrder and cancelAllLimitOrders need a grant and no key. The types are LimitOrderRequest, LimitOrderView, LimitOrderPage, CancelLimitOrderResult and CancelAllLimitOrdersResult, and StatusResponseOf<"limit_order"> is the status of a placed order. See SDK.

Errors

A refusal names its layer (Error layers). Every code is in Status & Errors.

Next steps

Executions

Idempotency, the timelock queue, owner approval and recovery.

Policies & Limits

The price bound, the USD budget and the rest of the policy.

Status & Errors

Statuses, retries and every error code.

SDK

The five limit-order methods and their types.