Documentation: API reference

API reference

The REST API behind Norr's MCP tools. Every /v1 route needs the vault's agent token as Authorization: Bearer <token>; a token is scoped to one vault and no route can withdraw, change rules or choose a destination. The MCP endpoint (/mcp on the MCP host) exposes the same operations as tools. /health, /attestation and /info are public.

The machine-readable spec is openapi.json (OpenAPI 3.1.0); this page is generated from it.

Servers

  • https://api.norr.finance: Hosted service. TLS terminates inside the attested CVM (check the certificate with scripts/verify-domain.mts). Runs on demand during the pilot.
  • https://85e1d6a557dae81985c9e30e28270f91bee5c0e9-8787.dstack-pha-prod5.phala.network: The same CVM through Phala's gateway.
  • http://localhost:8787: Local mock mode (pnpm dev:mock): fixed prices, no funds.

Authentication

Send the vault's agent token on every /v1 request: Authorization: Bearer <agent token>. Create one in the dashboard (Connect). A token works for one vault only.

Assets

What can be traded, and what is known about it.

GET /v1/assets

List tradable assets. Crypto by symbol and chain; tokenized stocks and ETFs by ticker, with every issuer that offers it and the smallest order that has been quoting. MCP tool: list_assets.

Query parameter Type
class crypto, equity Only crypto, or only tokenized stocks and ETFs.

Response 200 (AssetList):

Field Type
crypto object[]
equities object[]
equityNotice string
equityMinimumNote string
notice string

Other responses: 400, 401.

GET /v1/assets/check

Risk or eligibility verdict for one asset. Crypto: Scam Shield's risk level with reasons. Stocks: whether this vault may trade them, and the notice. Also any active NEAR Intents security incident touching the asset. MCP tool: check_asset.

Query parameter Type
asset string required. A symbol (SOL), a ticker (NVDA: routed to the best-priced issuer) or a NEAR Intents asset id.

Response 200 (AssetCheck):

Field Type
found boolean required
message string
class crypto, equity
ticker string
versions object[]
eligible boolean
notice string

Other responses: 400, 401.

GET /v1/market

Market data for one asset. Listed price and, for crypto, the read-only signals Scam Shield scores (liquidity, market cap, age) with its risk level. For stocks: price per issuer and the quoting minimum. Facts, not advice. MCP tool: get_market_data.

Query parameter Type
asset string required. A symbol (SOL), a ticker (NVDA: routed to the best-priced issuer) or a NEAR Intents asset id.

Response 200 (MarketData):

Field Type
found boolean required
message string
class crypto, equity
ticker string
source string
versions object[]

Other responses: 400, 401.

Trading

Price a trade (dry run) or request one.

POST /v1/quote

Price a trade without trading. Dry run: no funds move. Runs the same checks as a trade, so a trade that would be blocked returns the same blocked decision. MCP tool: get_quote.

Request body (TradeInput):

Field Type
side buy, sell required
asset string required
amountUsd number required
reason string The agent's reasoning, sealed to the owner's key; the service cannot read it back.

Response 200 (Quote or Blocked):

One of: Quote

One of: Blocked

Other responses: 400, 401.

POST /v1/trade

Request a trade. Checks the rules and the asset's risk, quotes, executes through NEAR Intents (in the confidential layer when the vault's funds are there), and verifies the result. Funds always stay in the vault. A blocked answer names the rule; adjust the request instead of resending it. MCP tool: trade.

Request body (TradeInput):

Field Type
side buy, sell required
asset string required
amountUsd number required
reason string The agent's reasoning, sealed to the owner's key; the service cannot read it back.

Response 200 (Decision):

One of: Executed

One of: Blocked

One of: PendingApproval

One of: Failed

Other responses: 400, 401.

Vault

Holdings, rules, results and history.

GET /v1/portfolio

Holdings in USD. Every holding with its layer (public or confidential), valued in USD, and the split between crypto and tokenized stocks. MCP tool: get_portfolio.

Response 200 (Portfolio):

Field Type
holdings object[] required
totalUsd number required
byClass object required

Other responses: 401, 503.

GET /v1/policy

The rules the agent must stay within. Planning view of the vault's rules, including what is left of today's spending cap. MCP tool: get_policy.

Response 200 (PolicyView):

Field Type
maxTradeUsd number required
dailySpendCapUsd number required
spentTodayUsd number required
spendRemainingTodayUsd number required
dailyLossCapUsd number required
maxEquityPct number required
allowedCrypto "any_safe" or string[] required
allowedEquities string[] required
cooldownSec number required
allowMediumRisk boolean required
equitiesEnabled boolean required
privacy public, prefer, require required
paused boolean required

Other responses: 401.

GET /v1/pnl

Profit and loss since the first trade. Per asset and in total: realized (sells at average cost) and unrealized (what is still held from Norr's buys, at today's listed price). Deposits have no known cost and are not counted. MCP tool: get_pnl.

Response 200 (Pnl):

Field Type
since string or null required
sinceMs number or null
scope string required
assets object[] required
totals object required
unpriced string[] required

Other responses: 401.

GET /v1/activity

Recent requests and outcomes. The last 20 trade requests, newest first. Swaps waiting for the owner's approval are settled here once approved. MCP tool: get_activity.

Response 200 (Activity):

Field Type
activity object[] required

Other responses: 401.

Public

Health and attestation; no token.

GET /health

Is the service up.

No token needed.

Response 200 (object):

Field Type
ok boolean required
mock boolean required
pricing ready, retrying required
mockOwner string Mock mode only.

GET /attestation

A fresh TDX quote bound to your nonce. The quote's report data is your nonce, padded with zeros. Check it with the dashboard's Verify screen or scripts/verify-attestation.mts.

No token needed.

Query parameter Type
nonce string required. 1 to 64 bytes of hex.

Response 200 (object):

Field Type
attested true required
nonce string required
quote string required. Hex TDX quote.
eventLog
commit string or null

Other responses: 400, 429, 503.

GET /info

The measured app configuration.

No token needed.

Response 200 (object):

Field Type
attested true required
appId string
composeHash string
appCompose string
commit string or null

Other responses: 503.

Decisions

What POST /v1/trade answers (Decision), by status:

Executed

Field Type
status "executed" required
txRef string required
filled object required
venue public, confidential
verification independent, custody-reported
warnings string[]

Blocked

Field Type
status "blocked" required
code BlockCode required
message string required
suggestedUsd number

PendingApproval

Field Type
status "pending_approval" required
requestId string required
message string required

Failed

Field Type
status failed, refunded required
message string required

Block codes and what they mean: MCP tools.