Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

REST API

Parcl exposes a validator API for live chain state and a REST API for hosted authentication, signing, indexed history, and explorer data.

Environments

EnvironmentValidator APIREST API
Mainnethttps://validator.v4.parcl.cohttps://api.v4.parcl.co
Devnethttps://v4-api.dev.parcllabs.comhttps://v4-rest-api.dev.parcllabs.com

The validator WebSocket uses /v1/ws on the selected validator host. Pin the expected chain ID before signing.

All responses are JSON unless an endpoint states otherwise. Prices use 8 decimals, sizes use 6, and USDC amounts use 6.

Naming and integer formats

Most validator responses use camel case, such as marketId and oraclePrice. GET /v1/fee-tiers, GET /v1/node/info, recent trades, and WebSocket events use snake case because they mirror protocol or event shapes.

Large integers can be decimal strings. Treat account balances, volumes, prices, sizes, and counters as arbitrary-precision integers before applying their scale.

Markets

GET /v1/markets

Returns the active markets for the selected environment. Paused markets and markets in settlement do not appear in this list. Query GET /v1/markets/{id} to inspect a known market in another state.

curl https://v4-api.dev.parcllabs.com/v1/markets

The response is an array. Each element has this shape:

[
  {
    "marketId": 0,
    "name": "NYC",
    "status": "Active",
    "markPrice": "58177000000",
    "bestBid": "58100000000",
    "bestAsk": "58200000000",
    "oraclePrice": "58035000000",
    "oracleStatus": "Active",
    "fundingRate": "-15800",
    "openInterestLong": "37460000",
    "openInterestShort": "37460000",
    "maxOpenInterest": "1400000000",
    "initialMarginRatioBps": 1000,
    "maintenanceMarginRatioBps": 500,
    "backstopAccountId": 5,
    "feeTiersEndpoint": "/v1/fee-tiers",
    "lastOraclePrice": "58035000000",
    "lastOracleTimestamp": 1712345678000,
    "oracleValidUntil": 1712433900,
    "tickSize": "1000000",
    "lastFundingTimestamp": 1712345678,
    "fundingIntervalSecs": 3600,
    "assetClass": "RealEstate",
    "priceBandBps": 1000,
    "interestRateMicroBps": 64,
    "depthThresholdLamports": "25000000000",
    "marginTiers": [
      {
        "notionalFloor": "0",
        "maxLeverage": 10,
        "maintenanceMarginRatioBps": 500,
        "maintenanceDeduction": "0"
      },
      {
        "notionalFloor": "500000000000",
        "maxLeverage": 5,
        "maintenanceMarginRatioBps": 1000,
        "maintenanceDeduction": "25000000000"
      }
    ]
  }
]

bestBid and bestAsk can be null when that side of the order book is empty.

feeTiersEndpoint is a discovery link to the canonical fee schedule. The market object does not include a fee rate because the rate also depends on account volume. backstopAccountId identifies the account that receives positions during a backstop liquidation, so a client can follow the resulting transfers. marginTiers is ordered by notionalFloor; a flat schedule has one row at floor zero. See markets and margin.

GET /v1/markets/{id}

Returns one market with the same shape.

GET /v1/markets/{id}/orderbook

{
  "marketId": 0,
  "bids": [{ "price": "58100000000", "size": "500000", "orderCount": 1 }],
  "asks": [{ "price": "58200000000", "size": "300000", "orderCount": 1 }]
}

GET /v1/markets/{id}/funding

Returns the current funding state for one market:

{
  "marketId": 0,
  "fundingRate": "69183",
  "cumulativeFunding": "2388785636613712714",
  "lastFundingTimestamp": 1779819896651,
  "fundingIntervalSecs": 3600,
  "maxFundingRateBps": 625
}

fundingRate is the running estimate for the next hourly settlement. cumulativeFunding is the per-market index that positions settle against. See funding.

GET /v1/markets/{id}/trades

Returns recent public fills. The response is an array and uses snake-case event fields:

[
  {
    "price": "68391000000",
    "size": "30000000",
    "side": "Long",
    "timestamp": 1787486431524,
    "taker_order_id": 219262738,
    "maker_order_id": 219262368,
    "tx_hash": "5b977ba3304f5f9c..."
  }
]

Accounts

GET /v1/accounts/{id}

Returns collateral, positions, open orders, volume, and account policy fields:

{
  "accountId": 12,
  "owner": "0x35504e68...",
  "mode": "Cross",
  "collateral": "21929491932",
  "positions": [
    {
      "marketId": 0,
      "side": "Long",
      "size": "64560188",
      "entryPrice": "58211606845",
      "unrealizedPnl": "-120297107",
      "cumulativeFunding": "0",
      "lastOraclePrice": "58090000000",
      "openedAt": 1712345678000,
      "margin_mode": "Cross",
      "leverage": 50,
      "isolated_margin": "0",
      "tierGrandfathered": false
    }
  ],
  "openOrders": [],
  "createdAt": 1712300000000,
  "volume30d": 37581522814,
  "feeTierVolume30d": 37581522814,
  "lifetimeVolume": 142581522814,
  "pendingActivation": false
}

prclBalance is the account's liquid PRCL balance as a decimal string in base units. availableCollateral is the amount of USDC available to transfer, also as a base-unit decimal string. It accounts for positions and open orders. Both tokens use six decimal places. PRCL is excluded from collateral and account equity.

pendingActivationFeeUsdc appears on an account that is awaiting its first qualifying deposit. agents appears when the account has approved agent keys.

GET /v1/accounts/by-owner/{pubkey}

Finds the personal account for a Parcl Chain public key. The key can include or omit the 0x prefix.

GET /v1/accounts/by-owner/{pubkey}/assets

Returns the owner's accounts, including subaccounts and managed vault accounts. This public read does not require authentication. An invalid public key returns HTTP 400. An owner without accounts receives an empty accounts array.

FieldMeaning
accounts[].accountIdAccount ID
accounts[].masterAccountIdParent ID for a subaccount; null for a root
accounts[].isVaultTrue for a vault root
accounts[].collateralAccount USDC balance
accounts[].availableCollateralUSDC available to transfer after margin reservations
accounts[].prclBalanceLiquid PRCL held by that account
accounts[].positionCountNumber of open positions
accounts[].openOrderCountNumber of open orders
unallocatedPrclPRCL awaiting assignment to a personal Master
stakedPrclOwner's delegated PRCL, separate from liquid account balances
unbondingPrclOwner's unbonding PRCL, separate from liquid account balances

accounts[].balances lists each asset's tokenId, symbol, decimals, total, available, and collateralEligible. unallocated lists token IDs and amounts awaiting personal Master. The named USDC/PRCL fields remain compatibility projections. Generic amounts are decimal strings in base units. Use each token's decimals to format them; USDC and PRCL both use six. Parse amounts as integers. Do not add staking holdings to each subaccount: they belong to the owner and their liquid entry and exit account is personal Master. The staking balance endpoint reports funds available from Master, or unallocated funds before Master exists. It does not sum spendable PRCL across subaccounts.

GET /v1/tokens

Public registry read. tokens contains id, symbol, name, and decimals. Use the ID to select an asset; symbols do not define identity. representations lists approved sources and their deposit/withdrawal flags. capabilities reports genericTransfers and atomicSubaccountClosure. Check these before submitting those actions.

GET /v1/transfers/recipient

Authenticated recipient lookup. Query kind is username, wallet, or account; value is the corresponding name, public key, or account ID. Wallet lookup accepts a Solana base58 public key or a 32-byte hexadecimal owner key. It resolves the personal Master for that key. Username lookup resolves the user's personal Master. An account ID selects that specific personal account.

Returns accountId, masterAccountId, owner, and isMaster. IDs are decimal strings. Invalid input returns 400; a missing or ineligible recipient returns 404.

GET /v1/transfers/history

Authenticated transfer history for the owner. Returns up to 50 items and a nullable nextCursor. Pass that cursor as ?cursor=... for the next page. Each item has blockHeight, eventIndex, timestamp, txHash, fromAccountId, toAccountId, fromOwner, toOwner, tokenId, amount, reason, and direction.

amount is a base-unit decimal string. IDs are decimal strings. reason is Transfer or SubaccountClose; direction is incoming, outgoing, or own. Own-account transfers appear once. History remains available after closure and starts with the generic transfer release. Invalid cursors return 400.

GET /v1/accounts/{id}/positions

Returns the positions array.

GET /v1/accounts/{id}/orders

Returns the open-orders array.

GET /v1/accounts/{id}/rate-limit

Returns the account's on-chain request budget and congestion quota. See request limits.

GET /v1/bridge/state?owner={owner}

Returns bridge state. The optional owner query adds two fields for that owner:

FieldMeaning
ownerThe requested public key as 64 lowercase hex characters
unclaimed_usdcAttested USDC awaiting account creation, as a base-unit decimal string

The query does not require an existing account. An owner with no unclaimed funding returns "0". A malformed owner key returns HTTP 400. Without the query, the response omits these two fields.

Use /v1/accounts/by-owner/{owner}/list to check for a personal account. Use /v1/node/info to verify the chain ID and /v1/treasury-config to read account_activation_fee_usdc. See funded account creation.

GET /v1/accounts/{id}/invites

Returns invitation eligibility and usage for the account.

FieldDescription
accountIdAccount ID
eligibleWhether the account can refer new users
allowanceTotal invitation allowance
consumedInvitations used
remainingInvitations available
lifetimeVolumeAccount lifetime trading volume
inviteOverrideAccount-specific allowance, or null
nextUnlockVolumeNull; invitations do not require trading volume

Oracle

GET /v1/oracle/{market_id}

Returns the current price, update date, timestamps, validity window, and Active, Stale, or Halted status.

{
  "marketId": 0,
  "price": "58035000000",
  "lastUpdateTimestamp": 1712345678000,
  "lastUpdateDate": 20260406,
  "status": "Active",
  "validUntil": 1712433900
}

GET /v1/oracle/{market_id}/history

Returns historical oracle points. time is Unix seconds. price uses 8 decimals. Real estate markets publish one point per day.

{
  "marketId": 0,
  "prices": [
    { "time": 1748217600, "price": "59738000000" },
    { "time": 1748304000, "price": "59855999999" }
  ]
}

Exchange configuration

GET /v1/fee-tiers

Returns the effective trading-fee schedule. Filter tiers to the market's assetClass, then choose the highest min_volume_30d at or below the account's feeTierVolume30d, the trailing 30-day volume of the account's family. A negative maker fee is a rebate. See the canonical fee table.

GET /v1/treasury-config

Returns the live account-activation, subaccount-capacity, vault-capacity, and open-order-cap settings. Amount and volume fields use scaled integer strings. The selected environment's response is authoritative; do not hard-code these values.

GET /v1/node/info

Returns protocol_version, binary_version, build_sha, block_height, block_timestamp, state_root, and chain_id. The binary and block fields change as the chain advances. Validate their shapes and pin only the expected chain_id: parcl-v4:mainnet:chain-1 for mainnet or parcl-v4:devnet:chain-2 for devnet.

Bridge state

GET /v1/bridge/state

Returns transfer availability, the withdrawal window, pending totals, token limits, and current limit usage. Amounts inside limits are decimal strings in each token's smallest unit.

The rolling response also includes each direction's current *_used value. These counters change with bridge activity. See Solana bridge for transfer stages and direct deposits.

Transactions

POST /tx/sign-and-submit

Host: REST API. Accepts an authenticated owner browser session or X-API-Key.

The request contains one transaction, a millisecond nonce, and a seconds timestamp. The hosted signer signs and forwards it after the applicable owner-session or API-key checks. See transactions for exact bodies and authentication for API-key variants.

POST /v1/tx

Host: validator API. Agent-key clients submit a direct signed envelope. The signature covers the UTF-8 bytes of JSON.stringify([chainId, transaction, nonce, timestamp]) using the exact submitted transaction bytes. See transactions for the contract.

Indexed account history

These REST API endpoints require an owner session or API key and return only owned-account data:

EndpointResult
GET /v1/accounts/{id}/tradesFill history
GET /v1/accounts/{id}/trades/csvFill history as CSV
GET /v1/accounts/{id}/ordersOrder history
GET /v1/accounts/{id}/fundingFunding-payment history

The JSON endpoints accept limit, offset, startTime, endTime, and marketId where applicable. Monetary values are scaled integer strings. The CSV endpoint returns all rows matching its filters.

Statistics

GET /v1/stats on the REST API returns aggregate exchange counts and volumes. Statistics are indexed data and can lag validator state.