# Welcome to Anchored

**The Global Digital Operating System for Real-World Assets.**

Anchored Finance provides institutional-grade infrastructure for the compliant issuance, redemption and distribution of tokenized stocks and fund products, fully backed 1:1 by underlying assets held in regulated custody.

Our platform is built for distribution partners such as exchanges, neobanks, wallets, and DeFi protocols, who want to offer tokenized real-world assets to their users without building the underlying infrastructure, legal framework, or broker relationships from scratch. It is equally built for professional investors who want direct, onchain access to U.S. equities and institutional fund strategies.

**What you'll find in these docs:**

* How Anchored tokenized stocks work: issuance, redemption, settlement mechanics and more
* Eligibility requirements and jurisdictional restrictions
* Trading hours and market availability
* Proof of reserves information

**Get started**

To learn more about Anchored or explore our product offerings, visit [anchored.finance](https://anchored.finance/). For questions, reach out at <info@anchored.finance>.

### Social Channels <a href="#social-channels" id="social-channels"></a>

Our official social channels are:

<table data-card-size="large" data-view="cards" data-full-width="true"><thead><tr><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><a href="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FEqjZ0RLcJc8dUzyhU8XG%2F64cebc6c19c2fe31de94c78e_X-vector-logo-download.png?alt=media&amp;token=659af41a-bd62-4d50-871d-8cf3c72f3efc">64cebc6c19c2fe31de94c78e_X-vector-logo-download.png</a></td><td><a href="https://x.com/AnchoredFi">https://x.com/AnchoredFi</a></td></tr><tr><td><a href="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FMVo2s3I1yjRMnzVimRmE%2F2496097.png?alt=media&amp;token=029201ec-ca7a-4d54-a1d5-da1f1c5230ba">2496097.png</a></td><td><a href="https://www.linkedin.com/company/anchored-fi/">https://www.linkedin.com/company/anchored-fi/</a></td></tr></tbody></table>


# Overview

#### What is Anchored Finance? <a href="#what-is-ondo-global-markets" id="what-is-ondo-global-markets"></a>

Anchored Finance is the digital operating layer for global capital markets. We give institutions and qualified investors a single platform to access tokenized versions of traditional financial instruments. Our first product is an institutional-grade tokenization platform that converts stocks, ETFs and funds into blockchain-based tokens. We provide the infrastructure for clients to access traditional public stocks, and institutional funds through blockchain rails.

Every Anchored token is fully backed 1:1 by the underlying asset. For our first live tokenized stock product, the underlying assets are purchased through a regulated U.S. broker and custodian and held within the fund structure described below. Tokens are minted and redeemed onchain via stablecoin settlement, removing the friction of traditional cross-border brokerage: no wire transfers, no multi-day settlement, no currency conversion delays. Our API allows partners and developers to embed tokenized stock trading directly into their own products.

#### What are Anchored tokenized stocks? <a href="#what-are-ondo-tokenized-stocks" id="what-are-ondo-tokenized-stocks"></a>

Anchored tokenized stocks are ERC-20 tokens that represent economic exposure to publicly traded U.S. equities. Each token is a receipt for a beneficial entitlement, held under a bare trust, to specified underlying fund shares. Those fund shares are backed 1:1 by the corresponding underlying stock, held in a segregated fund structure with an independent fund administrator calculating NAV daily.

Tokens follow a simple naming convention: the prefix `a` + the stock ticker. Apple (AAPL) becomes `aAAPL`, Tesla (TSLA) becomes `aTSLA`, and so on.

**How they work:**

* **1:1 backed.** Every token in circulation is backed by the corresponding underlying stock, with underlying assets held through the relevant brokerage and custody arrangements within the Anchored fund structure the tokens give entitlement to. This is not synthetic exposure. Real shares are held.
* **Stablecoin in, stablecoin out.** Mint by sending stablecoins, redeem back to stablecoins. No bank wires, no fiat intermediaries for the end user.
* **Fractional by default.** There is no minimum unit: you can hold any fraction of a token.
* **Live on Ethereum, Base, Arbitrum and Monad.** Anchored tokenized stocks are deployed on all three chains.
* **DeFi-native.** Tokens are standard ERC-20s and fully composable. This means not only can they be held on centralized exchanges but also they can be used as collateral in lending protocols, traded on DEXs, or integrated into any DeFi application that supports them.

**Who can access Anchored tokenized stocks?**

Anchored tokenized stocks are available to non-U.S. professional investors. All participants must complete KYC (for individuals) or KYB (for entities) before minting or redeeming directly on the platform. Certain jurisdictional restrictions apply.

**What you're getting. And what you're not.**

Anchored tokenized stocks provide economic exposure to the price performance of the underlying stock. They do not confer voting rights, shareholder communications, or any direct legal claim against the issuer of the underlying equity. Tokens can be redeemed at any time for stablecoins reflecting the current market value of the underlying stock.

**How are investors protected?**

Anchored takes a structural approach to investor protection rather than relying on operational promises alone:

* **Bankruptcy-remote fund structure.** Investor assets sit within a segregated portfolio that is legally ring-fenced from Anchored's operating entities and their creditors.
* **Independent fund administration.** A third-party fund administrator independently calculates and verifies NAV on a daily basis, providing an external check on all asset valuations.
* **Regulated custody and execution.** Underlying stocks are held through a U.S.-regulated broker-dealer with direct clearing membership, not routed through unregulated intermediaries.
* **Audited smart contracts.** All token contracts undergo independent security audits before deployment.
* **Transparent reporting.** Daily NAV disclosures, monthly reconciliation reports, and annual audits provide ongoing visibility into asset backing.


# Anchored Tokens

Anchored offers tokenized stocks and tokenized fund shares. See below for the currently available products and contract addresses.

### Tokenized stocks

All tokenized stocks below are available on Arbitrum, Base, Ethereum, and Monad. Each asset uses the same contract address on every supported network.

#### Network contract view

Each address below is identical on Ethereum, Monad, Base, and Arbitrum.

<table><thead><tr><th width="145.3125">Asset</th><th width="577.23046875">Ethereum, Monad, Base, and Arbitrum contract address</th></tr></thead><tbody><tr><td>aAAPL</td><td>0x17683e492d0C8910F7c0157D04af31Cb7A23Ad71</td></tr><tr><td>aAIQ</td><td>0x1D236E2EF49bf8b425a5d81332230FDfdAa20aee</td></tr><tr><td>aALLW</td><td>0x057a4712d82D83909b149f6e4390E5298FfDeb3C</td></tr><tr><td>aAMD</td><td>0xbdf82C0DAFCf73834d10639c0F0Bf14b84808C43</td></tr><tr><td>aAMZN</td><td>0x06f272082339A90e81e1DCB8AB892fD1a8c5E4C0</td></tr><tr><td>aANET</td><td>0xB8e03AD48dDdC2E415715F6DbeFb51839E756C25</td></tr><tr><td>aARKQ</td><td>0x4ebaF539FB82F35d09f24c709B4c7B9A56777c03</td></tr><tr><td>aARM</td><td>0x37bb22aF99a6C2B23Cfc2EA0cCB7151752a0fd5a</td></tr><tr><td>aASML</td><td>0xFAE6ba6D36a6388c5a944a9366E55B6597E4f8af</td></tr><tr><td>aAVGO</td><td>0x4dfbCd033662BC41de8996886E751613C2B8e8e5</td></tr><tr><td>aBIL</td><td>0x4FC5B9f8933597D3ecf84d0611687E1Dc8DD576f</td></tr><tr><td>aBNO</td><td>0xc924B71A10C356c15e3d7CB76ac8EFe8F5522347</td></tr><tr><td>aBOTZ</td><td>0xfd8ae3a6e660EFDfcE2Ae9bdCdCB81c9a959a846</td></tr><tr><td>aCCJ</td><td>0xDaBa319970C3502e152088E45e5a803e78Cf51D8</td></tr><tr><td>aCIEN</td><td>0xd90007E68aa0557E3e9FBf17140d00611DC793EC</td></tr><tr><td>aCOIN</td><td>0xD8c1DAe1c55B2fA349F78Ce34553E075AAD6b8A2</td></tr><tr><td>aCONI</td><td>0x2C82E424f8B36352bAe1bCd585c82938B8B78EC8</td></tr><tr><td>aCRCL</td><td>0x72e4F625B68f8d7A08dFb5A88065D6bB90052098</td></tr><tr><td>aCRM</td><td>0x8339D77b003589cF90F17729595AFE05AD951ac5</td></tr><tr><td>aCSCO</td><td>0x991c1f370Adbab08E1F7978B01Cb1DC022b902BB</td></tr><tr><td>aDELL</td><td>0x87Db2cEAC8b2321443d0BfEf67340096867C91BA</td></tr><tr><td>aEBAY</td><td>0x33f74aC6aa7a73Aca8aB09C52D9158061F634ff3</td></tr><tr><td>aETN</td><td>0x678ed8ccc3f3D8FF2873D6BeaB5748E4321C1670</td></tr><tr><td>aEWY</td><td>0xA01a050440b8D77Fc868Ff33d290A2DAb5b79366</td></tr><tr><td>aFLKR</td><td>0x4F9b7d336b1972dD4C93CA250121AacAa6B083AA</td></tr><tr><td>aFORM</td><td>0xbe10e0C583e46ff8D9A5a6aB578A89b7e49ad005</td></tr><tr><td>aGDX</td><td>0x7b17054C9621930F3CDd38177217c2b73956856a</td></tr><tr><td>aGEV</td><td>0xdBd41398c970a1649C7Eec1D72c9D50E0Aa3B095</td></tr><tr><td>aGLD</td><td>0x3e4A2f26Fc4F92d92D7CD1e49ddaDe32869D00A4</td></tr><tr><td>aGME</td><td>0x8E18aC2b7EbDd781e7a15C333f3b80EEd8De4A27</td></tr><tr><td>aGOOGL</td><td>0xBDe676CDF5564Ef64CCD8555Aa9B56867D8D1aD5</td></tr><tr><td>aHOOD</td><td>0x5a4860adDCc094FcE026384caeEcb1e634DD9af4</td></tr><tr><td>aINTC</td><td>0x126250964E05B9E34d025e9D3b309349cf92402A</td></tr><tr><td>aIONQ</td><td>0xC8c3bbd0aF3f10293d75dd468C51F3f81Fc22FEe</td></tr><tr><td>aMETA</td><td>0xa1847139cbd660ABC2f7b889d7CBCF18C56407fb</td></tr><tr><td>aMRNA</td><td>0xDa230A7EC7aFf66E62ff3e225C3D9C42093C23ae</td></tr><tr><td>aMRNX</td><td>0x69825E4Cf138fe7441a75Af72dA1AE8F9e720434</td></tr><tr><td>aMRVL</td><td>0x870e3495f5D7F0872Ad7c0fbDD163016AE9122b5</td></tr><tr><td>aMSFT</td><td>0x73E9EB2C7a4B4E8c68232b31Ea0F1246963D0375</td></tr><tr><td>aMSTR</td><td>0x294F40996134D067B56dcbACBf6a36396BBBeA7a</td></tr><tr><td>aMU</td><td>0xc54ce75193a68602bC01FfD2B112DA3948EB14a7</td></tr><tr><td>aNBIS</td><td>0x822594e4bC4C8237E77e5620744d3f383e77d4fe</td></tr><tr><td>aNOW</td><td>0x6B97A52C6877FaF6F3836377B37e4A0A27EdDE01</td></tr><tr><td>aNVD</td><td>0x9b4D9b20EaC87C4DA9912cdbDC111d991eEF0681</td></tr><tr><td>aNVDA</td><td>0x701193374879131f923532987c7Ef363a91a80eB</td></tr><tr><td>aORKA</td><td>0x344FCa3683cd01aa5833E67179F826080bda98fc</td></tr><tr><td>aPANW</td><td>0xB66340a2BC5F95b127534Ba5F24827802B9Bc7EE</td></tr><tr><td>aPLTR</td><td>0xB95956daacE89226185FB696C2Cc3F0d9BBFD4e3</td></tr><tr><td>aQBTS</td><td>0xdfA678fA8d208eD3125e84a184fb39f2a22817A4</td></tr><tr><td>aQQQ</td><td>0x1446501E886c7f830DB9b494A1890cBCCC072f57</td></tr><tr><td>aQTUM</td><td>0x472A83495B50Ce62b124CAbfef7A7C0DB067C1e7</td></tr><tr><td>aRDDT</td><td>0x167ef0d9AE3D001146865eC8Aa4A7a78b048B615</td></tr><tr><td>aRGTI</td><td>0xC3b236FB3cd15e3D996f3B49C0eE034Bc18ACCF9</td></tr><tr><td>aRKLB</td><td>0x8bCe7712CA1eFc613CE73F9471aD2388DAc09413</td></tr><tr><td>aSDS</td><td>0x9B5803E173b3118d70A17C3be0BABdd912A4000E</td></tr><tr><td>aSKDD</td><td>0x215CCE3E783fC7FAfBed758D55ef5B654fD69A34</td></tr><tr><td>aSKHY</td><td>0x6E8568ba7B43138d9210959a9523155e274550C9</td></tr><tr><td>aSLV</td><td>0xa6d6d48D778539103d379A66697ACC22dD7B1d3C</td></tr><tr><td>aSMCI</td><td>0xfd38813A547b30155914383919cebE83a98435fA</td></tr><tr><td>aSMH</td><td>0x74110FB3858D91418227007851362672514925Ef</td></tr><tr><td>aSNDK</td><td>0x57e2613fa6193c11913299CBdC1C8cb4916c15e8</td></tr><tr><td>aSOXL</td><td>0x6910aCdC21a86dAd4FdE233764FdaC4F4cE187E8</td></tr><tr><td>aSPCG</td><td>0xA67F4594e3c8441a58D1df95F1AB7D3d65367Afd</td></tr><tr><td>aSPCX</td><td>0x12473790e09D415ABAc7441401F7AbeC64Fa959C</td></tr><tr><td>aSPY</td><td>0x4716Cfb68C73BfF797Eea4f94ffAD8d198aEfC4B</td></tr><tr><td>aSQQQ</td><td>0x3D054231Ed348b1C52684E2477f935FE06DAfd85</td></tr><tr><td>aSTX</td><td>0xC060d393df9ca0E96fb5434FF3223c085c4B2e2A</td></tr><tr><td>aTBT</td><td>0xC614D4aD49ec4F4854D70cb4fd788DDb5c3Fe41e</td></tr><tr><td>aTLT</td><td>0x5DA938Ad48C46BD22CA362A91517ce2c16367d09</td></tr><tr><td>aTQQQ</td><td>0xB57B6C37526CECDDDbf92DA1783b7F4b4B53d45F</td></tr><tr><td>aTSLA</td><td>0x10FAD4A60Adb421F8F5Ca6f9f2eAf2DbC110E146</td></tr><tr><td>aTSLZ</td><td>0x3f670133caa4d10Cf726028A68602114c1A3F15c</td></tr><tr><td>aURA</td><td>0x7e952B8C28D855804c7FE8d64ecac30ace16C4dA</td></tr><tr><td>aUSO</td><td>0x7388ED3371407471D48637b4Ad8445b8D4Fc3f8f</td></tr><tr><td>aVRT</td><td>0x0b45e5aFEa928030988704ef60995d8925b91CD6</td></tr><tr><td>aVST</td><td>0x49ccCd75B2b0Fb9ccD8c1d2a5D313e050C52fA89</td></tr><tr><td>aWDC</td><td>0x49E30F2D4a1b9a1766F0675ADaF04f70681Fbb63</td></tr><tr><td>aWEN</td><td>0x4644Fd1eab16A21969B4c16Be8A2D5c986033F2a</td></tr><tr><td>aWMT</td><td>0xbDcd7e902861094164D4b4048Ac62D3897a32721</td></tr><tr><td>aXLK</td><td>0xf63AD58f1D4D1276eA0De2490689942303d2D446</td></tr></tbody></table>

### Tokenized funds

Anchored currently offers the following tokenized fund shares on Ethereum:

<table><thead><tr><th width="146.70703125">Asset</th><th width="580.27734375">Ethereum contract address</th></tr></thead><tbody><tr><td>aDHF</td><td>0x0ca21052CF746bCAC4807DbbE0A15269CC83EA3C</td></tr><tr><td>aLSF</td><td>0x5925Fbeed8B63e8246798b7c9f1dC706c047d95D</td></tr><tr><td>aAIF</td><td>0xb75480e350F82633050f5A38045C03B24b293271</td></tr></tbody></table>

#### Which networks are Anchored tokens available on?

Anchored tokenized stocks are available on Arbitrum, Base, Ethereum, and Monad. Anchored fund shares are currently available only on Ethereum.

#### Token standard

Anchored tokenized stocks and fund shares follow the ERC-20 standard. They work with ERC-20-compatible wallets and applications.

#### Are Anchored tokenized stocks transferable?

Yes. Anchored tokenized stocks and fund shares are freely transferable on their deployed chains. Administrators can pause transfers during emergencies. While paused, transfers, mints, and redemptions cannot occur.

#### Decimals

All Anchored tokenized stocks and fund shares use 18 decimals.


# Eligibility

This page outlines who may subscribe for, acquire, or redeem Anchored tokenized products, and the jurisdictional restrictions that apply

Specific eligibility requirements are assessed during the onboarding process. Applicants will be asked to provide documentation confirming their qualifying status as part of KYC/KYB review.

### Who Can Invest in Anchored Finance Products?

**Anchored Finance tokenized products are designed for professional and qualified investors**, subject to local laws and Anchored's compliance policies. Our products are primarily intended for non-U.S. and non-China investors who meet specific regulatory definitions in their jurisdictions.

Certain individuals and entities are restricted or prohibited from purchasing, holding, or redeeming these tokens due to regulatory, sanctions, or licensing limitations.

This page provides a detailed overview of:

* Jurisdictions where participation is prohibited
* Other compliance-based scenarios that may limit onboarding or use of the platform

### Jurisdictions Where Access Is Prohibited

Individuals who reside in, are citizens of, or entities that are incorporated in or primarily operate from any of the jurisdictions listed below ("Prohibited Persons") are not permitted to subscribe for, purchase, or redeem Anchored tokenized products:

* Afghanistan
* Algeria
* Belarus
* Canada
* China (excluding Hong Kong SAR)
* Cuba
* Democratic People's Republic of Korea (DPRK / North Korea)
* Eritrea
* Iran
* Libya
* Myanmar
* Morocco
* Nepal
* Russia
* Somalia
* South Sudan
* Sudan
* Syria
* Ukraine regions under sanctions, including Crimea, Donetsk (DNR), Luhansk (LNR), Kherson, Zaporizhzhia, and Sevastopol
* United States — including all states, territories, possessions, and federal districts
* Venezuela

#### FATF High-Risk Jurisdictions

To strengthen our AML/CFT compliance framework, Anchored Finance includes jurisdictions identified by the Financial Action Task Force (FATF) as having significant strategic deficiencies in their anti-money laundering and counter-terrorist financing regimes. This currently includes the Democratic People's Republic of Korea (DPRK), Iran, and Myanmar.

#### Additional U.S.-related restriction:

Persons located in, transacting from, or classified as "U.S. persons" (as defined under Regulation S of the U.S. Securities Act), or acting for the benefit of a U.S. person, are prohibited from acquiring or redeeming Anchored tokens.

Anchored Finance may also bar participation if doing so would violate sanctions, securities regulations, internal risk policies, or token-issuer governing documents. Entities in which Prohibited Persons hold, directly or indirectly, a controlling interest or 50% or more of the beneficial ownership are treated as prohibited.

### Other Restrictions

Anchored Finance also applies compliance screening unrelated to geography. The platform may deny onboarding or block usage for:

* Persons or entities subject to sanctions (OFAC, FATF, UN, EU, UK, etc.)
* Politically exposed persons (PEPs), where risk cannot be mitigated
* Entities engaged in high-risk, unlicensed, or prohibited industries
* Users who fail KYC/KYB verification or provide insufficient documentation
* Entities controlled by prohibited or sanctioned individuals

Certain business categories may also be unsupported depending on risk and licensing requirements.

### Questions or Support

If you have questions about eligibility, onboarding requirements, or whether your jurisdiction is supported, please contact our compliance team at:

<info@anchored.finance>


# How to Onboard

Getting started with our platform is straightforward. Follow these steps to complete your onboarding and begin minting stock tokens:

#### **1. Sign Up with Email**

Create your account by providing a valid email address and setting a secure password.

<figure><img src="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FQdFaAfm3l9m9lENmsWGb%2FHow-to-onboard%201.%20sign%20Up.png?alt=media&amp;token=b44907d9-e243-4ddf-b009-608e212c8f31" alt=""><figcaption></figcaption></figure>

#### **2. Verify Your Email Address**

Check your inbox for a verification email from our platform. Click on the verification link to confirm your email address and activate your account.

#### **3. Choose Your Account Type**

Select the account type that best fits your needs:

* **Individual Account**: For professional investors acting in their personal capacity
* **Entity Account**: For institutions, corporations, trusts, or other legal entities

<figure><img src="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FjD3Auwi9pFsqN9qMrfgI%2FHow-to-onboard%203.%20Choose%20account%20type.png?alt=media&amp;token=2c67dacc-b836-4853-8b15-6c509e196074" alt=""><figcaption></figcaption></figure>

#### **4. Complete Account Details**

If you selected an **Entity Account**, you'll need to provide additional information:

* Entity Name (legal name of your organization)
* Entity's Registered Country

<figure><img src="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FXurSbaZBxij7NupP7LYH%2FHow-to-onboard%204.%20Enter%20Entity%20Name.png?alt=media&amp;token=4cb49482-23a9-4d25-b81f-e67b377523cd" alt=""><figcaption></figcaption></figure>

#### **5. Account Setup Complete**

Your account is now set up! You can proceed to the verification process based on your account type:

* **Individual Accounts**: Complete KYC (Know Your Customer)
* **Entity Accounts**: Complete KYB (Know Your Business)

<figure><img src="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FEnU74h4zHe9AzAYCUq5l%2Fcard.png?alt=media&amp;token=b545936e-6411-4c6f-92c5-bce6904cdb88" alt=""><figcaption></figcaption></figure>

#### **6. Start Minting**

Once our compliance team has reviewed and approved your KYC or KYB submission, you'll receive a confirmation notification via email. Your account will be fully activated, and you can begin minting and redeeming stock tokens on our platform.

<figure><img src="https://2654876225-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FgeAju15aOUUuPkzUHaVR%2FHow-to-onboard%206.%20Mint.png?alt=media&amp;token=fafffb71-8b41-4b89-a27b-258cb595f095" alt=""><figcaption></figcaption></figure>


# Investment & Redemption

{% hint style="info" %}
This page explains how to mint (buy) and redeem (sell) Anchored tokenized stocks directly onchain, including supported payment methods, minimums, and what to expect at each step.
{% endhint %}

***

## **Investing (Issuance)**

<details>

<summary>What is the minimum investment amount?</summary>

The minimum amount to mint tokenized stocks is $100,000 USDC. After the first mint, there is no consequent minimum minting amount.

</details>

<details>

<summary>Can I buy fractional tokens?</summary>

Yes. Tokens are divisible. You can mint or hold any fractional amount.

</details>

<details>

<summary>How does Issuance Work?</summary>

Issuing tokenized stocks with Anchored settles onchain once the underlying order has filled.

#### **Step-by-step**

1. Choose the stock you want to purchase.
2. Confirm the amount you'd like to buy.
3. Pay with a supported stablecoin (USDC initially).
4. Anchored mints your tokenized stock and delivers it directly to your wallet.

</details>

<details>

<summary>What currencies can I use to buy Anchored tokenized stocks?</summary>

Purchases are completed using **USDC**.

</details>

<details>

<summary>Which wallets are supported?</summary>

Anchored tokenized stocks use the **ERC-20 standard**, meaning they can be held in:

* MetaMask
* Rabby Wallet
* Trust Wallet
* OKX Wallet
* Coinbase Wallet
* Ledger, Fireblocks, BitGo (via supported custodial workflows)
* Any EOA or smart contract wallet that supports ERC-20 tokens

Note: centralized exchanges that are partners of Anchored also support Anchored tokens.

</details>

<details>

<summary>How long does issuance take?</summary>

Tokens are minted after the relevant fill and once authorised settlement conditions are satisfied. An unfilled order mints nothing, and a partial fill mints only the filled amount.

</details>

***

## **Redeeming**

Redemptions allow you to convert tokenized stocks back into stablecoins. The process mirrors issuance and is equally fast.

<details>

<summary>How do Redemptions Work?</summary>

1. Select the tokenized stock you want to redeem.
2. Enter the amount you want to convert.
3. Confirm the transaction from your wallet.
4. Anchored burns the tokens and returns **USDC** to your wallet.

Redemptions are subject to fees, liquidity, market hours, partner rules and compliance checks.

</details>

<details>

<summary>How much can I redeem and for which currencies?</summary>

The minimum redemption amount is **$10.00.**&#x20;

You can redeem into:

* **USDC** (default)
* Future support for other stablecoins or fiat transfers may be added as regulatory approvals allow.

</details>

<details>

<summary>Are redemptions always instant?</summary>

No. Redemption is subject to fees, liquidity, market hours, partner rules and compliance checks. If fiat payouts become supported, processing times may differ again depending on banking rails and jurisdictional requirements.

</details>

***

## **Additional Notes**

#### **Do I receive ownership rights in the underlying stock?**

No. Anchored tokenized stocks provide **economic exposure** to the underlying asset, not legal ownership. That means:

* No shareholder voting rights
* No statutory reporting rights
* No direct claims against the issuer of the security

However, you can always redeem tokens for their underlying value in stablecoins.

## **Need help?**

For questions about issuance, redemptions, payment methods, or onboarding, reach out at: **<info@anchored.finance>**


# Trading Hours

### Trading Hours

Anchored tokenized stocks can be traded throughout the U.S. trading week, from Sunday evening through Friday evening (Eastern Time). Trading follows the same session structure as the underlying U.S. equity markets, with the addition of overnight access.

#### Trading Sessions

<table><thead><tr><th width="176.08984375">Session</th><th width="188.61328125">Hours (ET)</th><th>Notes</th></tr></thead><tbody><tr><td>Overnight</td><td>8:00 PM – 4:00 AM</td><td>Available via alternative trading venues. Lower liquidity and wider spreads are typical.</td></tr><tr><td>Pre-Market</td><td>4:00 AM – 9:30 AM</td><td>Early access before the U.S. market open.</td></tr><tr><td>Regular Market</td><td>9:30 AM – 4:00 PM</td><td>Standard U.S. market hours. Deepest liquidity and tightest spreads.</td></tr><tr><td>After-Hours</td><td>4:00 PM – 8:00 PM</td><td>Post-close trading. Useful for reacting to earnings or late-breaking news.</td></tr></tbody></table>

There may be brief pauses of a few minutes during transitions between sessions as the underlying trading venues rotate. Trading is not available on weekends or U.S. market holidays.

**What to expect outside core hours**

Liquidity during pre-market, after-hours, and overnight sessions is generally lower than during core market hours. This can mean wider bid-ask spreads, greater price volatility, and smaller maximum order sizes. For larger orders, we recommend trading during core hours or splitting orders across multiple transactions.

**When trading may be unavailable**

Trading in all assets is paused during weekends, U.S. market holidays, and scheduled platform maintenance. Individual assets may also be temporarily halted during corporate actions (such as dividends or stock splits) or if internal risk thresholds are triggered.


# Corporate Actions

### Dividend Distribution

When a company pays a dividend on a stock you hold through Anchored, you receive your proportional share in USDC, net of taxes, fees and operational costs. We distribute dividends in USDC stablecoins, automatically depositing them into the wallet associated with your Anchored account.

#### How It Works

**What Are Dividends?**

Dividends are periodic payments that companies distribute to shareholders from their profits. When you hold stock tokens on our platform, you receive your proportional share of these dividends based on your token holdings, net of taxes, fees and operational costs.

**Payment Method**

All dividends are distributed as USDC (USD Coin), which is automatically deposited into the wallet associated with your Anchored account and becomes immediately available for placing new orders.

No action required - dividends are credited automatically.


# Fees & Taxes

#### Fees

* Deposit fee: 0 bps
* Withdrawal fee: 21 bps
* Buy / mint fee: 10 bps
* Redemptions: allowed
* Redemption frequency: 24/5
* Minimum order / subscription:
  * Directly with Anchored: USD 90
  * Through our integration partners: USD 1
* Minimum redemption:
  * Directly with Anchored: USD 90
  * Through our integration partners: USD 1

#### Taxes

For tax-related questions, please consult a qualified tax advisor in your jurisdiction. Tax treatment of stock tokens may vary depending on your country of residence and personal circumstances.


# FAQs

#### Overview

<details>

<summary>What is Anchored?</summary>

Anchored is the digital operating layer for global capital markets, providing onchain infrastructure for tokenized real-world assets. The platform enables eligible users and distribution partners to access tokenized products such as tokenized stocks and tokenized funds, with asset backing, issuance, redemption, compliance and settlement infrastructure designed for institutional use.

</details>

<details>

<summary>What products does Anchored offer?</summary>

Anchored’s product set includes tokenized stocks and tokenized fund products. Tokenized stocks provide onchain exposure to individual listed equities and ETFs. Tokenized fund products provide onchain access to fund strategies through tokens linked to the relevant underlying fund interests. Product availability, terms and eligibility may vary by jurisdiction, partner platform and product.

</details>

<details>

<summary>Is Anchored a broker, exchange or fund manager?</summary>

Anchored is a multi-entity platform with different entities performing different roles. The group comprises a few core entities. Anchored Capital Ltd is the token issuer and operates the Anchored dApp. Anchored Finance SPC is the CIMA registered segregated portfolio company used as the underlying fund vehicle. Anchored Labs Ltd provides technology and services and operates the anchored.finance website. Anchored Advisors Ltd is a BVI FSC Approved Manager. Brokerage, custody, administration and other regulated functions may be provided by third-party service providers depending on the product.

</details>

<details>

<summary>Who can use Anchored products?</summary>

Anchored products are intended for eligible users who meet the applicable onboarding, KYC/KYB, jurisdiction and investor-eligibility requirements. Availability depends on the product, user type, distribution partner, jurisdiction and applicable legal restrictions. Anchored products are not intended to be offered where such offer or access would be unlawful.

</details>

<details>

<summary>Who is excluded from Anchored products?</summary>

Anchored products are not intended for U.S. persons or for residents of mainland China. Hong Kong, Macau and Taiwan are not within that restriction. Other eligibility restrictions can vary by product and jurisdiction, and sanctions-related exclusions apply separately.

</details>

<details>

<summary>Why does Anchored use blockchain infrastructure?</summary>

Blockchain infrastructure can make ownership records, transfers, settlement instructions and verification data more transparent and programmable. Anchored uses onchain infrastructure to support token issuance, transfer restrictions, settlement, compliance controls, proof-of-reserves / proof-of-solvency workflows and integration with partner platforms.

</details>

#### Anchored entities and operating structure

<details>

<summary>Which entity issues Anchored tokens?</summary>

Anchored Capital Ltd, a BVI-incorporated company, is the issuer of Anchored tokenized products unless a specific product document states otherwise.

</details>

<details>

<summary>What is Anchored Finance SPC?</summary>

Anchored Finance SPC is a Cayman Islands segregated portfolio company and fund vehicle. The SPC structure allows assets and liabilities of different product portfolios to be segregated from one another. This is designed so that one product portfolio is not exposed to the liabilities of another portfolio.

</details>

<details>

<summary>What is a segregated portfolio?</summary>

A segregated portfolio is a legally separated portfolio within an SPC. Assets and liabilities attributed to one segregated portfolio are intended to be ring-fenced from other segregated portfolios. Anchored uses this structure to separate product lines such as tokenized stocks and tokenized funds.

</details>

<details>

<summary>What does Anchored Labs Ltd do?</summary>

Anchored Labs Ltd provides technology and services for the Anchored platform, including infrastructure supporting token issuance, product operations and integrations, but it is not the token issuer. It also operates the anchored.finance website. The Anchored dApp is operated by Anchored Capital Ltd.

</details>

<details>

<summary>Why does Anchored use multiple entities?</summary>

Anchored uses multiple entities to separate issuance, fund management, technology services, asset-holding structures and regulatory responsibilities. This structure is intended to support risk isolation, clearer governance, compliance scoping and institutional partner requirements.

</details>

<details>

<summary>Are all Anchored entities regulated in the same way?</summary>

No. Different Anchored entities have different roles and regulatory statuses. For example, Anchored Finance SPC is a Cayman registered fund, Anchored Advisors Ltd is a BVI FSC Approved Manager, and Anchored Capital Ltd acts as the token issuer. Users should refer to the relevant product documents for the exact entity, role and regulatory status applicable to a product.

</details>

#### Tokenized stocks

<details>

<summary>What are Anchored tokenized stocks?</summary>

Anchored tokenized stocks are blockchain-based tokens designed to provide economic exposure to underlying listed stocks or ETFs. Each tokenized stock is intended to track the corresponding underlying stock or ETF, subject to the applicable product terms, fees, market conditions and legal documentation.

</details>

<details>

<summary>What do I own when I hold an Anchored tokenized stock?</summary>

A holder owns a token issued by Anchored Capital Ltd representing a beneficial entitlement, under a bare trust, to underlying fund shares, which in turn provide economic exposure to the corresponding underlying stock or ETF. Holding a tokenized stock does not generally make the holder a direct shareholder of the underlying public company and does not generally provide direct shareholder voting rights.

</details>

<details>

<summary>Are Anchored tokenized stocks backed by the underlying stock?</summary>

Anchored tokenized stocks are backed by the corresponding underlying stock or ETF. The operating model is that underlying shares are purchased through brokerage and custody arrangements and held within the relevant Anchored fund structure. The token is a receipt for a beneficial entitlement, under a bare trust, to the corresponding underlying fund shares. Token issuance occurs after execution / fill confirmation. Backing, reconciliation and proof workflows may vary by product and venue.

</details>

<details>

<summary>When are new tokenized stock tokens minted?</summary>

Tokenized stock minting is linked to execution of the underlying stock purchase. In the standard flow, user or partner proceeds are routed for execution, the underlying stock is purchased, and Anchored mints the corresponding tokenized stock after the relevant fill and authorized settlement conditions are satisfied. Unfilled orders do not result in minting, and partial fills should only mint the filled amount.

</details>

<details>

<summary>How does redemption of tokenized stocks work?</summary>

In a redemption or sell flow, the token is reserved or burned according to the applicable order and settlement process, the corresponding underlying stock is sold, and net proceeds are returned to the user in the supported payout currency, subject to fees, liquidity, market hours, partner rules and compliance checks.

</details>

<details>

<summary>Can Anchored tokenized stocks trade outside normal U.S. market hours?</summary>

Anchored offers 24/5 extended trading hours for tokenized stocks and ETFs, and tokens may also be transferable onchain or traded on supported partner platforms, depending on the chain, venue and product configuration. Primary issuance and redemption still depend on the ability to execute, settle or reconcile the underlying stock transaction through the relevant broker and market infrastructure, so they follow market hours rather than 24/5.

</details>

<details>

<summary>How is the price of an Anchored tokenized stock determined?</summary>

Pricing is generally linked to the price of the underlying stock or ETF, as sourced through the relevant broker, market-data provider or platform mechanism. Secondary-market prices may differ from the underlying reference price due to liquidity, fees, market hours, supply and demand, spreads and venue-specific conditions.

</details>

<details>

<summary>Do Anchored tokenized stocks pay dividends?</summary>

When the underlying stock pays a dividend, the economic benefit is passed through to holders in USDC, automatically and with no action required, net of taxes, fees and operational costs.

</details>

<details>

<summary>How are stock splits and other corporate actions handled?</summary>

Corporate actions such as stock splits, reverse splits, mergers or ticker changes may be reflected through token adjustments, balance adjustments, contract updates, issuer actions or other operational processes, depending on the product and chain. The objective is to preserve the intended economic exposure, but treatment may vary based on the corporate action and applicable documentation.

</details>

<details>

<summary>Do tokenized stock holders receive voting rights?</summary>

Tokenized stock holders do not receive direct voting rights in the underlying public company. The token is designed to provide economic exposure, not direct registered shareholder status.

</details>

<details>

<summary>What fees apply to tokenized stocks?</summary>

Fees may include minting, redemption, withdrawal, trading, partner-platform, spread, brokerage, custody, currency-conversion or blockchain network fees. The applicable fee schedule can vary by product, chain and distribution partner, and should be checked on the relevant live product page or order interface.

</details>

<details>

<summary>Where can users buy Anchored tokenized stocks?</summary>

Anchored tokenized stocks may be available through supported partner platforms, venues or Anchored interfaces, depending on the product, jurisdiction and user eligibility. Availability can change over time as new integrations go live.

</details>

<details>

<summary>Which blockchains support Anchored tokenized stocks?</summary>

Anchored tokenized stocks are live on Ethereum, Monad, Base and Arbitrum. Tokenized fund shares are currently available on Ethereum only.

</details>

#### Tokenized funds

<details>

<summary>What are Anchored tokenized fund products?</summary>

Anchored tokenized fund products are tokens that provide eligible users with onchain access to fund strategies. The token represents a beneficial interest or economic exposure linked to the relevant underlying fund shares held through the applicable Anchored structure.

</details>

<details>

<summary>How are tokenized fund products structured?</summary>

The typical structure is that Anchored Capital Ltd issues the token, while the relevant segregated portfolio of Anchored Finance SPC holds the corresponding underlying fund interests. This structure is intended to connect the token held by the user with the underlying fund exposure while keeping product portfolios legally segregated.

</details>

<details>

<summary>What is the difference between a tokenized stock and a tokenized fund?</summary>

A tokenized stock is designed to track a single listed stock or ETF. A tokenized fund is designed to provide exposure to a fund strategy, which may itself hold a diversified portfolio of assets or strategies. Tokenized funds often have different valuation, subscription, redemption, liquidity, notice-period and risk characteristics from tokenized stocks.

</details>

<details>

<summary>Are tokenized funds backed by underlying fund shares?</summary>

Tokenized fund products are designed to be backed by the relevant underlying fund shares or fund interests held through the corresponding Anchored structure. The exact valuation, subscription and redemption mechanics depend on the relevant fund, share class, offering documents and product terms.

</details>

<details>

<summary>How are tokenized fund prices calculated?</summary>

Tokenized fund pricing is generally based on the net asset value or price reported for the relevant underlying fund or share class, adjusted as described in the applicable product documentation. Unlike listed stocks, fund NAVs may be calculated daily, monthly or at another frequency depending on the underlying fund.

</details>

<details>

<summary>How often can users subscribe to tokenized fund products?</summary>

Subscription frequency depends on the specific tokenized fund and the underlying fund’s dealing schedule. Some fund products may permit monthly subscriptions, while others may have different dealing cycles, notice periods or cut-off dates.

</details>

<details>

<summary>How often can users redeem tokenized fund products?</summary>

Redemption frequency depends on the underlying fund and product terms. Some fund products may have quarterly redemption windows, notice periods, fund-level gates, lock-ups or delayed payout mechanics. Users should check the relevant product factsheet and offering documents before subscribing.

</details>

<details>

<summary>Are tokenized fund products as liquid as tokenized stocks?</summary>

Not necessarily. Tokenized funds may have longer subscription and redemption cycles because they depend on the valuation and liquidity terms of the underlying fund. A tokenized fund may be transferable onchain or through supported venues, but primary redemption may still be subject to fund-level dealing dates, gates, notice periods and settlement timelines.

</details>

<details>

<summary>Who manages the underlying funds used in Anchored tokenized fund products?</summary>

The underlying fund manager depends on the specific product. Anchored may provide tokenized access to a fund managed by a third-party underlying fund manager, while Anchored entities handle issuance, product structuring, platform operations or investment-management roles as applicable. Product pages should clearly distinguish the Anchored issuer / platform from any third-party underlying fund manager.

</details>

#### Asset backing, custody and verification

<details>

<summary>How does Anchored verify that tokenized products are backed?</summary>

Anchored’s architecture includes reconciliation and proof workflows intended to verify that issued tokens correspond to underlying assets or fund interests. For tokenized stocks, this can include broker/custody data and onchain supply data. For tokenized funds, this can include fund administrator, NAV and holding records. The exact verification mechanism may vary by product.

</details>

<details>

<summary>What is proof of reserves?</summary>

Proof of reserves is a verification process intended to show that issued tokens are backed by corresponding assets or interests. In Anchored’s context, proof workflows are designed to connect offchain asset records with onchain token supply so users and partners can assess whether product backing is consistent with issued tokens.

</details>

<details>

<summary>Where are the underlying assets held?</summary>

Underlying assets are held through the relevant product structure and third-party service providers. For tokenized stocks, underlying shares are purchased through brokerage infrastructure and held in custody arrangements within the relevant segregated portfolio, in the same structure used for tokenized funds. For tokenized funds, the relevant segregated portfolio holds underlying fund interests. Exact custody and service-provider details should be checked in product documentation.

</details>

<details>

<summary>What happens if there is a mismatch between tokens and underlying assets?</summary>

Anchored’s issuance, redemption and reconciliation processes are designed to prevent mismatches by linking minting and burning to underlying execution, custody and fund records. If an exception occurs, Anchored may use operational, compliance or smart-contract controls to investigate, pause, restrict or correct activity as permitted by the applicable product terms.

</details>

<details>

<summary>What happens if a broker, custodian, administrator or other service provider has an issue?</summary>

Anchored products depend on third-party providers for functions such as brokerage, custody, administration, banking, pricing, market data and blockchain infrastructure. A disruption or failure at a service provider may affect issuance, redemption, pricing, settlement, reporting or access. These risks should be reviewed in the relevant product risk disclosures.

</details>

#### Compliance, eligibility and controls

<details>

<summary>Why does Anchored require KYC/KYB?</summary>

Anchored products involve regulated financial assets and are subject to sanctions, AML, investor-eligibility and jurisdictional restrictions. KYC/KYB helps verify user identity, jurisdiction, eligibility and compliance status before access is granted.

</details>

<details>

<summary>Can Anchored restrict transfers?</summary>

Yes. Certain Anchored tokenized products may include compliance controls that restrict transfers, pause activity, freeze addresses or block prohibited transactions where required for sanctions, fraud prevention, security, policy, technical or settlement reasons. These controls are part of operating tokenized real-world assets in a compliant manner.

</details>

<details>

<summary>Are Anchored tokens securities?</summary>

The legal characterization of a token depends on the product, jurisdiction and applicable documentation. Anchored products provide exposure to financial assets and may be subject to securities, funds, derivatives, financial-promotion, AML or other regulatory requirements. Users should rely on the relevant offering documents and obtain professional advice where needed.

</details>

<details>

<summary>Is this investment advice?</summary>

No. Website and FAQ content is for general informational purposes only and should not be treated as investment, legal, tax or accounting advice. Users should assess the relevant risks and consult professional advisers before investing.

</details>

<details>

<summary>What jurisdictions does Anchored operate in?</summary>

Anchored uses a multi-jurisdictional structure, including BVI and Cayman entities, with additional jurisdictional initiatives in progress or planned. Entity roles and regulatory status differ by jurisdiction and should not be generalized across the group.

</details>

<details>

<summary>Can anyone integrate Anchored products into an exchange, wallet or dapp?</summary>

Integrations are subject to Anchored’s technical, legal, compliance and commercial review. Partners may need to satisfy requirements relating to user eligibility, KYC/KYB, jurisdictional controls, order routing, custody, disclosures, data reporting and ongoing monitoring.

</details>

#### Risks and user responsibilities

<details>

<summary>What are the main risks of Anchored tokenized products?</summary>

Risks may include market risk, liquidity risk, tracking error, valuation risk, fund-gating risk, redemption delays, counterparty risk, custody risk, smart-contract risk, blockchain network risk, regulatory risk, tax risk, and risks arising from third-party service providers. Product-specific risks are described in the relevant offering documents and disclosures.

</details>

<details>

<summary>Can the value of Anchored tokens go down?</summary>

Yes. Anchored tokens are linked to financial assets whose value can rise or fall. Users may lose some or all of the amount invested.

</details>

<details>

<summary>Are returns guaranteed?</summary>

No. Anchored does not guarantee returns. Past performance of an underlying stock, ETF, fund or strategy is not a reliable indicator of future results.

</details>

<details>

<summary>What should users review before buying an Anchored product?</summary>

Users should review the product page, factsheet, fee schedule, risk disclosures, offering documents, eligibility requirements, redemption terms, supported chains, service-provider information and any jurisdiction-specific restrictions before investing.

</details>

<details>

<summary>Where can users get official information?</summary>

Users should rely on official Anchored websites, dapp pages, product documentation, factsheets, partner-platform disclosures and direct communications from Anchored or approved distribution partners. Users should be cautious of unofficial links, impersonators and third-party summaries.

</details>


# Legal


# Disclaimer


# Terms of Service


# Extended Hours & Overnight Trading Risk Disclosure

Angela to copy in the Alpaca one <https://files.alpaca.markets/disclosures/library/ExtHrsOvernightRisk.pdf>


# Privacy Policy


# Cookies Policy


# Trust & Transparency

## Proof of Reserves

Anchored tokenized stocks are 1:1 backed by the underlying stocks, held through a licensed U.S. broker-dealer. We have partnered with [Accountable](https://accountable.capital/) to verify this and to issue an independent Proof of Reserves that attests to our underlying reserves.

### How does Anchored Proof of Reserves work?

[Accountable](https://accountable.capital/) has full access to our custody accounts via API endpoints and can independently check the status of our underlying reserves at any time. They verify that the number of shares held by our custodian matches or exceeds the total token supply on-chain. This information is then published publicly so anyone can verify that all tokens are fully backed.

### How frequently is Anchored PoR updated?

Anchored Proof of Reserves is updated every 15 minutes.

### Where can I verify reserves?

Please verify the reserves here: <https://accountable.anchored.finance/>


# Smart Contract Audits

The Anchored Smart Contracts have been audited by the leading security firms, [Sherlock](https://sherlock.xyz/) and [Three Sigma](https://threesigma.xyz/).

Please find the full audit reports below:

* [The Stock Contract Audit Report](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2F8Te8C7AqJDC9jSrd0LF0%2F20260402-sherlock.pdf?alt=media\&token=ad51d120-b299-4843-9b4e-f79fc63a8f5e)
* [The Fund Contract Audit Report](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzoanOJXsy8CjcaPvtHGj%2Fuploads%2FpKtkK3sj6SP9T9kDNmhB%2F20260525-threesigma-fund.pdf?alt=media\&token=7bb76e7d-0ea5-414d-bae9-e8db9d445333)


# RWA API

Documentation for integrators using the **Anchored** RWA API to build stock trading, cash movement, and portfolio services.

Authenticate with API key + HMAC on every request. Choose **self-submit on-chain** or **One Click delegated** execution for orders, cash operations, and stock operations.

Current mainnet deployments are on Base, Monad, and Ethereum. Use `x-api-p: Anchored` for the Anchored product unless your API key is explicitly provisioned for another product context.

## Base URL

Production:

```
https://rwa-api.anchored.finance/rwa/trading
```

All paths start with `/api/v1`. Example:

```
GET https://rwa-api.anchored.finance/rwa/trading/api/v1/symbols
```

For HMAC authentication, the `URI` uses `/api/v1/...` only — no domain or `/rwa/trading` prefix.

## Live reference

| Resource         | URL                                                                |
| ---------------- | ------------------------------------------------------------------ |
| OpenAPI snapshot | `reference/openapi.snapshot.json` (refreshed 2026-07-03 from test) |
| Live OpenAPI     | `https://rwa-api.anchored.finance/rwa/trading/api-docs`            |

## Reader path

| Step | Topic                                          | Doc                                                                                                                                        |
| ---- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 1    | Product and contract mental model              | [getting-started/product-and-contracts.md](/trading-api/getting-started/product-and-contracts)                                             |
| 2    | API integration playbook                       | [getting-started/trader-questions.md](/trading-api/getting-started/trader-questions)                                                       |
| 3    | Setup and response format                      | [getting-started/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/getting-started/README.md) |
| 4    | API key and HMAC authentication                | [authenticate/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/authenticate/README.md)       |
| 5    | Holdings and positions                         | [portfolio/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/portfolio/README.md)             |
| 6    | Symbols, quotes, history                       | [market/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/market/README.md)                   |
| 7    | Market and limit orders                        | [trading/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/trading/README.md)                 |
| 8    | Cash deposits and withdrawals                  | [cash/](/trading-api/cash-operations/cash)                                                                                                 |
| 9    | Stock deposits and withdrawals                 | [stock/](/trading-api/stock-operations/stock)                                                                                              |
| 10   | First API trade quickstart                     | [guides/quickstart-first-trade.md](/trading-api/guides/quickstart-first-trade)                                                             |
| 11   | End-to-end flows                               | [guides/](/trading-api/guides/guides)                                                                                                      |
| 12   | Demo code (Node.js + viem)                     | [guides/demo-code.md](/trading-api/guides/demo-code)                                                                                       |
| 13   | Status, troubleshooting, and production checks | [reference/](/trading-api/reference/reference)                                                                                             |

## Execution modes

| Mode        | Who signs on-chain         | Use when                                              |
| ----------- | -------------------------- | ----------------------------------------------------- |
| Self-submit | Your wallet or custodian   | You control private keys; call `/calldata` then `/tx` |
| One Click   | Server via delegated proxy | User signs EIP-712 once; call `/send` endpoints       |

See [guides/self-submit-on-chain.md](/trading-api/guides/self-submit-on-chain) and [guides/one-click-flow.md](/trading-api/guides/one-click-flow).

## Production Helpers

| Need                           | Doc                                                                                          |
| ------------------------------ | -------------------------------------------------------------------------------------------- |
| Debug stuck requests or txs    | [reference/troubleshooting.md](/trading-api/reference/troubleshooting)                       |
| Interpret lifecycle states     | [reference/status-model.md](/trading-api/reference/status-model)                             |
| Map API endpoints to contracts | [reference/api-contract-map.md](/trading-api/reference/api-contract-map)                     |
| Choose chain/product context   | [reference/environments-and-chains.md](/trading-api/reference/environments-and-chains)       |
| Review sample responses        | [reference/sample-responses.md](/trading-api/reference/sample-responses)                     |
| Test before production         | [reference/integration-test-checklist.md](/trading-api/reference/integration-test-checklist) |


# Introduction

The RWA API is a RESTful API for Anchored tokenized stock trading. It covers market data, portfolio, orders, cash deposits and withdrawals, and optional One Click delegated execution.

## Capabilities

* **43 endpoints** across market data, portfolio, orders, cash, stock, and One Click
* **Market and limit orders** with self-submit or delegated execution
* **Deposits and withdrawals** of cash tokens
* **Portfolio** balances and stock positions
* **Multi-chain mainnet**: Base, Monad, and Ethereum
* **Testnets**: Monad Testnet and Base Sepolia
* **HMAC-SHA256** request authentication

## Audience

Partner developers integrating RWA trading APIs for order submission, cash operations, and portfolio reconciliation.

Read [product-and-contracts.md](/trading-api/getting-started/product-and-contracts) first for the on-chain model (`StockRouter`, `Cashier`, `Stock`, settlement, portfolio balances). Then use [trader-questions.md](/trading-api/getting-started/trader-questions) as the practical API integration playbook.

## Before you begin

Obtain an API key and secret, configure IP whitelist, and confirm `chainId + productType + access` scopes. See [authenticate/headers-and-permissions.md](/trading-api/authentication/headers-and-permissions).

## Document version

* Doc version: 1.0
* Last updated: 2026-07-03
* Derived from `anchored-gitbook` with OpenAPI cross-check


# Conventions

## Base URL

Production environment:

```
https://rwa-api.anchored.finance/rwa/trading
```

All API paths start with `/api/v1`:

```
GET /api/v1/symbols
```

Full production URL:

```
https://rwa-api.anchored.finance/rwa/trading/api/v1/symbols
```

> **HMAC authentication note:** For HMAC calculation, the `URI` only uses `/api/v1/symbols` — not the domain or `/rwa/trading` prefix.

## Unified response structure

All endpoints return:

| Field    | Type                  | Description                       |
| -------- | --------------------- | --------------------------------- |
| `code`   | number                | Business status. `200` = success. |
| `errMsg` | string                | Error message. Empty on success.  |
| `data`   | object / array / null | Payload.                          |
| `uuid`   | string / null         | Request UUID.                     |
| `t`      | number / null         | Server timestamp.                 |

Success example:

```json
{
  "code": 200,
  "errMsg": "",
  "data": {
    "symbol": "AAPL"
  },
  "uuid": null,
  "t": null
}
```

### Pagination

Paginated `data`:

| Field   | Type   | Description             |
| ------- | ------ | ----------------------- |
| `total` | number | Total matching records. |
| `rows`  | array  | Current page.           |

Parameters:

| Parameter | Default | Constraints                        |
| --------- | ------- | ---------------------------------- |
| `page`    | `1`     | Treated as `1` if < 1.             |
| `limit`   | `10`    | Treated as `10` if < 1; max `100`. |

## Error handling

Business errors use HTTP `400` with `code` and `errMsg` in the body.

| code    | errMsg                  | Common cause                                                  |
| ------- | ----------------------- | ------------------------------------------------------------- |
| `401`   | `Unauthorized`          | Invalid key, signature, nonce, timestamp, IP, or permissions. |
| `500`   | `Server internal error` | Validation failure, missing config, downstream error.         |
| `10000` | `Unsupported chainId`   | `x-api-chain-id` not supported.                               |
| `10001` | `Unsupported product`   | `x-api-p` not in public list.                                 |
| `10002` | `ChainId is missing`    | Missing chain ID header.                                      |
| `10003` | `Product Id is missing` | Missing product type header.                                  |


# RWA Product Overview

This page explains the contract and accounting model behind the RWA API. The API does not replace on-chain rules. It helps you **build `StockRouter` calldata**, **submit or delegate transactions**, and **track state** across wallet balances, `Cashier`, `Stock`, and asynchronous settlement.

If you are debugging a concrete trade, start with [trader-questions.md](/trading-api/getting-started/trader-questions). This page explains the system design; the playbook turns it into request, execution, and reconciliation checks.

## Overall Design

The RWA API supports funding, market and limit orders, cash and stock movement between wallet and contracts, and portfolio state queries. It behaves like a trading account at the API layer, but accounting and permissions are enforced by on-chain contracts. The API prepares the right transactions and tracks asynchronous results after those transactions are mined.

The system is built from on-chain contracts plus backend processing. The contracts hold accounting state and enforce the transaction path. Backend processing connects that on-chain state to market execution, final settlement, status updates, and API indexing.

Core on-chain contracts:

| Contract         | Role                                                                                                                                                                        |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `StockRouter`    | Public entrypoint. It receives transactions, uses ERC-20 allowance as spender when wallet tokens are needed, and calls `Cashier` or `Stock` with the original user address. |
| `Cashier`        | Tracks `mUSD`. The API surfaces this as `mUsdBalance`. Deposits increase it; withdrawals deduct it.                                                                         |
| `Stock`          | Tracks stock order state and stock tokens credited to users as `Stock.stockBalance`, surfaced by the API as `exchangeBalance`. Plain sells spend this balance.              |
| `OneClickRouter` | Optional delegated execution router. It forwards approved One Click actions to `StockRouter` while preserving the original user address.                                    |

With these contracts, a user can:

| User need       | What the product supports                                                                                                        |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Fund account    | Convert approved USDC into `mUSD`.                                                                                               |
| Buy stock       | Use `mUSD`, or use `/orders/with-deposit/*` to deposit cash and buy in one transaction.                                          |
| Sell stock      | Sell from `exchangeBalance`, or use `/orders/with-deposit/*` to deposit approved wallet stock and sell in one transaction.       |
| Withdraw cash   | Convert `mUSD` back to USDC.                                                                                                     |
| Move stock      | Use `/stock/deposits/*` to deposit wallet stock into `Stock`, or `/stock/withdrawals/*` to withdraw `exchangeBalance` to wallet. |
| Track portfolio | Read wallet balances, `mUsdBalance`, `exchangeBalance`, orders, and cash operation status.                                       |

The API prepares `StockRouter` transactions and indexes the lifecycle after submission. A mined transaction is not always the final business state; orders, cash operations, and portfolio balances can update after backend processing and settlement.

## Core Accounting Concepts

### mUSD

`mUSD` is a 1:1 USD-backed accounting unit reflecting real-time purchasing power. It is a digital representation of credit exclusively for Anchored RWA trading. `mUSD` is not a cryptocurrency, stablecoin, or transferable virtual asset. In this API guide, treat `mUSD` as the accounting balance a user can use to buy RWA stock or request a withdrawal.

| Concept              | Where it lives   | What it means                                                                                                                                                                         |
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mUSD`               | `Cashier`        | Used for buys and withdrawals. The API surfaces this as `mUsdBalance`.                                                                                                                |
| USDC wallet balance  | User wallet      | ERC-20 cash token. Must be deposited before it becomes `mUSD`.                                                                                                                        |
| Stock wallet balance | User wallet      | ERC-20 stock token held directly by the user. `StockRouter` can pull it only after user approval.                                                                                     |
| `Stock.stockBalance` | `Stock` contract | Accounting record for ERC-20 stock tokens held by `Stock` and credited to the user. The API surfaces this as `exchangeBalance`. Bought stock lands here; plain sells spend from here. |
| `walletAllowance`    | ERC-20 allowance | Whether `StockRouter` can pull a wallet token for a deposit or other token-pulling flow.                                                                                              |

Stock `walletBalance` and `exchangeBalance` are different. `walletBalance` is the ERC-20 stock token in the user's wallet. `exchangeBalance` is the API view of `Stock.stockBalance`, where stock is held by `Stock` and credited to the user. Plain sells spend `exchangeBalance`; wallet-held stock must be approved before `StockRouter` can pull it into `Stock` for selling.

### Deposit and Withdrawal Conversion

Cash movement is not just an on-chain token transfer. Deposited USDC ultimately needs to become USD usable for trading and settlement, and withdrawals need cash to come back before USDC can be paid out. That final cash path can take time.

To reduce API-visible waiting time, `Cashier` uses pre-funded buffers. When a buffer can safely cover the request, `Cashier` can apply the result immediately while final cash settlement catches up later.

Deposits convert wallet cash tokens into `mUSD`. The user first approves `StockRouter` as the cash token spender, then submits a deposit; `StockRouter` transfers the token to `Cashier`. If the deposit is instant, `Cashier` credits `mUSD` immediately. If it is queued, `mUSD` is credited after final cash settlement.

Withdrawals convert `mUSD` back into wallet cash tokens. The user requests a withdrawal through `StockRouter`, and `Cashier` deducts `mUSD`. If the withdrawal is instant, USDC is sent to the wallet immediately. If it is queued, USDC is sent after final cash settlement.

A mined transaction means the request reached the contracts. For queued operations, the final `mUSD` credit or USDC payout can happen later. See [cash/buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism) for buffer rules.

## Buy and Sell Paths

* **Plain buy:** spends existing `mUSD`.
* **Order-with-deposit buy:** uses approved cash token allowance, requires instant deposit, credits `mUSD`, then places the buy in one transaction.
* **Plain sell:** spends existing `exchangeBalance`, the API view of `Stock.stockBalance`.
* **Order-with-deposit sell:** transfers approved wallet stock into `Stock`, then places the sell in one transaction.

Buy paths lock `mUSD` before execution. A plain buy uses existing `mUSD`; an order-with-deposit buy first transfers approved cash token to `Cashier` and credits `mUSD`, but only when instant deposit is available and the buffer can cover the conversion.

```mermaid
sequenceDiagram
    participant U as User
    participant R as Contract: StockRouter
    participant C as Contract: Cashier
    participant S as Contract: Stock
    participant B as Backend bots

    alt Plain buy
        U->>R: place buy order
        R->>C: Lock existing mUSD
    else Order-with-deposit buy
        U->>R: deposit cash and place buy
        R->>C: Transfer cash token and credit mUSD
        R->>C: Lock mUSD
    end

    B->>B: Execute order
    B->>C: Apply mUSD spend or refund
    B->>S: Credit bought stock
    U->>U: Query API for order and balances
```

Sell paths lock stock before execution. A plain sell uses existing `exchangeBalance`; an order-with-deposit sell first transfers approved wallet stock into `Stock` and credits it there.

```mermaid
sequenceDiagram
    participant U as User
    participant R as Contract: StockRouter
    participant S as Contract: Stock
    participant C as Contract: Cashier
    participant B as Backend bots

    alt Plain sell
        U->>R: place sell order
        R->>S: Lock exchangeBalance
    else Order-with-deposit sell
        U->>R: deposit wallet stock and place sell
        R->>S: Transfer wallet stock and credit stockBalance
        R->>S: Lock stockBalance
    end

    B->>B: Execute order
    B->>S: Return unfilled stock if needed
    B->>C: Credit mUSD proceeds
    U->>U: Query API for order and balances
```

Market buys specify maximum `mUSD` to spend; market sells specify stock quantity. Limit orders specify quantity, limit price, and `timeInForce`; current production contracts accept only `DAY`. Limit orders can remain open and can be canceled while open. `txHash` is available as soon as the transaction is broadcast. `orderId` is created by the on-chain placement transaction and becomes available after the transaction is mined and indexed.

Cash endpoints are only for cash-token flows into or out of `Cashier`. Use `/stock/deposits/*` and `/stock/withdrawals/*` for stock token movement.

Any router flow that pulls wallet tokens requires ERC-20 **approve** first. Cash deposits require approval for the cash token; stock deposits require approval for the stock token. See [cash/deposits.md](/trading-api/cash-operations/deposits).

## Fees

Fees can appear in both cash operations and order results. Do not hardcode fee assumptions; read the returned fields from operation and order responses.

| Area            | Common fields                                          | Meaning                                                              |
| --------------- | ------------------------------------------------------ | -------------------------------------------------------------------- |
| Cash operations | `amount`, `creditAmount`, `feeAmount`                  | Token amount, resulting `mUSD`, and cash operation fee when present. |
| Order history   | `mintFee`, `protocolFee`, `settlePay`, `settleReceive` | Trading/mint/protocol fees and final fill amounts when present.      |

For deposits, the credited `mUsdBalance` may differ from the token amount if a fee applies. For orders, final received stock or cash depends on traditional-market execution: orders can fill at the executed price, partially fill, or receive no fill. Use settlement fields such as `settlePay`, `settleReceive`, `mintFee`, and `protocolFee` as the authoritative final amounts, not only the original order input.

## Contract stack (integrator view)

State-changing transactions go through **`StockRouter`**. When wallet tokens are needed, `StockRouter` uses the user's ERC-20 allowance as spender and transfers the tokens to `Cashier` or `Stock`; it does not custody deposits as the final destination.

```mermaid
flowchart TB
    User[User wallet]
    OCR[OneClickRouter optional]
    Router["StockRouter<br/>API calldata target"]

    Cashier["Cashier<br/>mUSD"]
    Stock["Stock<br/>orders and stockBalance"]

    User -->|"direct tx"| Router
    User -.->|"EIP-712 delegate"| OCR
    OCR -->|"ERC-2771 forward"| Router

    Router --> Cashier
    Router --> Stock

    Cashier -.- C1["cash deposits and withdrawals<br/>change mUSD"]
    Stock -.- S1["orders<br/>stockBalance"]
```

Use `x-api-p: Anchored` for Anchored RWA trading. The active API docs do not require other product contexts.

## Router operations map to API flows

Calldata responses give `toAddress`, `value`, and `callData` for your wallet client. `toAddress` is the `StockRouter` address. See [guides/demo-code.md](/trading-api/guides/demo-code).

| User action              | Router method      | Self-submit endpoint                         | One Click endpoint              |
| ------------------------ | ------------------ | -------------------------------------------- | ------------------------------- |
| Deposit cash             | `deposit`          | `POST /cash/deposits/calldata` then `/tx`    | `POST /cash/deposits/send`      |
| Withdraw cash            | `withdraw`         | `POST /cash/withdrawals/calldata` then `/tx` | `POST /cash/withdrawals/send`   |
| Market buy or plain sell | `placeMarketOrder` | `POST /orders/calldata` then `/tx`           | `POST /orders/send`             |
| Limit buy or plain sell  | `placeLimitOrder`  | `POST /orders/calldata` then `/tx`           | `POST /orders/send`             |
| Cancel limit             | `cancelLimitOrder` | `DELETE /orders/{orderId}/calldata`          | `DELETE /orders/{orderId}/send` |

Stock deposit and withdrawal are exposed through `/stock/deposits/*` and `/stock/withdrawals/*`.

## Portfolio API vs on-chain state

Use `GET /users/{userId}/balance` as the API view of wallet and exchange state.

| Field             | Meaning                                   | Integration note                                                         |
| ----------------- | ----------------------------------------- | ------------------------------------------------------------------------ |
| `mUsdBalance`     | `mUSD` tracked by `Cashier`               | Use for buy power and withdrawable credit                                |
| `walletBalance`   | ERC-20 tokens in wallet                   | Custody balance; `StockRouter` needs allowance before it can pull tokens |
| `exchangeBalance` | API name for `Stock.stockBalance`         | Use for plain sell availability                                          |
| `walletAllowance` | Token approval to spender / `StockRouter` | Check before token-pulling flows                                         |

Bought stock normally appears as `exchangeBalance` first because the ERC-20 stock tokens are held by `Stock` and credited to the user there. A user can withdraw stock from `Stock.stockBalance` to wallet custody. If wallet-held stock should be sold, the user must approve `StockRouter`; the selected flow can then deposit the stock into `Stock.stockBalance` separately or as part of the sell transaction. For API checks, use `mUsdBalance` for buy power and `exchangeBalance` for sell power.

## Two execution modes (same contracts)

| Mode        | How it works                                                                                                                |
| ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| Self-submit | API returns calldata; the user wallet signs and broadcasts the `StockRouter` transaction; the integration records `txHash`. |
| One Click   | User signs delegation once; `/send` submits through `OneClickRouter` to the same `StockRouter` methods.                     |

One Click is scoped for safety: the delegate wallet is bound to one user wallet, limited to supported RWA router actions, cannot freely transfer user ERC-20 tokens, and can be disabled.

## Design principles

| Principle           | What it means for integrators                                                                                                                                               |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Router-only entry   | API calldata targets `StockRouter`; state-changing integrations should not call `Cashier` or `Stock` directly.                                                              |
| Lock then settle    | Open orders lock `mUSD` or `Stock.stockBalance`; final balances update asynchronously.                                                                                      |
| Off-chain execution | Quotes and fills come from trading services; chain state catches up asynchronously.                                                                                         |
| Wallet vs exchange  | Portfolio shows both wallet and exchange balances; plain sells use `exchangeBalance`, while wallet-held stock can be pulled into `Stock` by an approved `StockRouter` flow. |
| Cash timing         | Deposits/withdrawals can be instant or queued; watch `operationStatus`.                                                                                                     |

## Where to go next

| Step            | Doc                                                                                                                                     |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Authenticate    | [../authenticate/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/authenticate/README.md) |
| Trader playbook | [trader-questions.md](/trading-api/getting-started/trader-questions)                                                                    |
| Portfolio       | [../portfolio/overview.md](/trading-api/portfolio/overview)                                                                             |
| Trading         | [../trading/overview.md](/trading-api/trading/overview)                                                                                 |
| Cash            | [../cash/](/trading-api/cash-operations/cash)                                                                                           |
| Demo code       | [../guides/demo-code.md](/trading-api/guides/demo-code)                                                                                 |
| Reference       | [../reference/](/trading-api/reference/reference)                                                                                       |

Deep contract docs: [anchored-contracts/docs/contract-architecture.md](https://github.com/AnchoredLabs/anchored-contracts/blob/main/docs/contract-architecture.md) · [anchored-contracts/docs/flows/](https://github.com/AnchoredLabs/anchored-contracts/blob/main/docs/flows/README.md)


# API Integration Playbook

Use this page as the practical operating guide for an RWA API integration. Before submitting orders, moving cash, or reconciling portfolio state, verify these request and state checks.

The most important habit is to separate **wallet state**, **mUSD**, **exchangeBalance**, and **final settlement state**. The API connects these systems, but they do not update at the same time.

## Integration Mental Model

```mermaid
sequenceDiagram
    participant Client as Integrator client
    participant API as Trading API
    participant Wallet as User wallet
    participant OCR as OneClickRouter
    participant Router as StockRouter
    participant Cashier as Cashier
    participant Stock as Stock

    Client->>API: GET state
    API-->>Client: mUsdBalance, exchangeBalance, orders

    alt Self-submit
        rect rgb(232, 244, 255)
            Client->>API: POST /calldata
            API-->>Client: toAddress, value, callData
            Client->>Wallet: submit transaction
            Wallet->>Router: execute calldata
            Client->>API: POST /tx with txHash
        end
    else One Click
        rect rgb(246, 239, 255)
            Client->>API: POST /send
            API->>OCR: submit delegated tx
            OCR->>Router: forward as user
        end
    end

    Router->>Cashier: update mUSD
    Router->>Stock: update orders / stockBalance
    Cashier-->>API: indexed state
    Stock-->>API: indexed state
```

Diagram color key: blue is self-submit, purple is One Click.

For self-submit requests, call the API to build `StockRouter` calldata, submit the transaction with the user wallet, then record `txHash`. For One Click requests, call `/send`; the API submits through `OneClickRouter`. For state reads, the API indexes `Cashier` and `Stock` into fields such as `mUsdBalance`, orders, and `exchangeBalance`.

`StockRouter` enforces on-chain entry, `Cashier` accounts for `mUSD`, and `Stock` accounts for orders and `Stock.stockBalance`. Build integrations around the async lifecycle instead of assuming a trade is final when the transaction is mined.

## Discover Tradable Stocks

Start every trading flow from the symbol list. Treat a stock token as tradable only when the API marks it tradable for the current `chainId` and `x-api-p`.

1. Call `GET /api/v1/symbols`.
2. Keep only symbols where `tradable` is `true`.
3. Call `GET /api/v1/config` for fee rates, cashier buffer state, and per-token deposit/withdraw limits.
4. Use `contractAddress` as `stockAddress` when building orders.
5. Refresh quote context with `GET /api/v1/prices/{symbol}`.
6. Check `GET /api/v1/corporate-action?symbol=AAPL` when splits/dividends may affect downstream accounting.

Do not hardcode token addresses unless your release process also verifies they match the active API response.

## Check Buying Power

For plain buys, the important value is `mUsdBalance`, not the cash token `walletBalance`. A user can have USDC in their wallet and still have no `mUSD` until a deposit happens. If the cash token is approved and instant deposit is available, `/orders/with-deposit/*` can deposit and place the buy in one transaction.

| Field             | API meaning                                       |
| ----------------- | ------------------------------------------------- |
| `mUsdBalance`     | `mUSD` available for buys and withdrawals         |
| `walletBalance`   | ERC-20 tokens in wallet; not automatically `mUSD` |
| `walletAllowance` | Whether deposit can succeed on-chain              |

Use `mUsdBalance` for plain market buys and limit buys. If it is insufficient, deposit cash first. When cash token approval and instant deposit conditions are met, `/orders/with-deposit/*` can deposit and place the buy in one transaction.

## Check Stock Available To Sell

For plain sells, the important value is `exchangeBalance`. `walletBalance` means the user owns an ERC-20 stock token in their wallet, but it is not yet credited inside `Stock`.

Do not treat wallet stock as plain-sell balance. A plain sell uses `exchangeBalance`, the API view of `Stock.stockBalance`. To sell wallet-held stock with separate calls, approve the stock token and call `/stock/deposits/*` first. To deposit and sell in one transaction, use `/orders/with-deposit/*` after stock token approval.

## Prepare Deposits Correctly

Deposit means: **wallet cash token -> mUSD -> buy power**. Track the conversion so the integration does not treat wallet balance as spendable `mUSD`.

Before building deposit calldata:

1. Check wallet cash balance.
2. Check allowance with `GET /api/v1/users/{userId}/balance?spenderAddress={spender}`.
3. Request ERC-20 approval from the owner wallet if `walletAllowance` is too low.
4. For self-submit, build deposit calldata and submit the returned `StockRouter` transaction.
5. For One Click, call `/cash/deposits/send` after delegation is enabled.
6. Record `txHash` for self-submit flows and poll the deposit operation.

If allowance is too low, `/cash/deposits/calldata` can still return calldata, but the chain transaction will fail.

## Place A Market Buy

```mermaid
sequenceDiagram
    participant T as Client
    participant API as Trading API
    participant R as StockRouter
    participant C as Cashier
    participant TS as Trading service

    alt Self-submit
        rect rgb(232, 244, 255)
            T->>API: POST /orders/calldata
            T->>R: submit returned calldata
        end
    else One Click
        rect rgb(246, 239, 255)
            T->>API: POST /orders/send
            API->>R: submit via OneClickRouter
        end
    end
    R->>R: placeMarketOrder buy notional
    R->>C: Lock max mUSD spend
    TS->>TS: Execute at best available price
    TS->>C: Apply mUSD spend or refund
```

Market buy input is `notional`: the maximum `mUSD` amount to spend. The final fill may spend less and refund the rest. The order is not economically final until settlement has credited stock and refunded unused `mUSD`.

## Place A Market Sell

```mermaid
sequenceDiagram
    participant T as Client
    participant API as Trading API
    participant R as StockRouter
    participant Stock as Stock
    participant TS as Trading service
    participant C as Cashier

    alt Self-submit
        rect rgb(232, 244, 255)
            T->>API: POST /orders/calldata
            T->>R: submit returned calldata
        end
    else One Click
        rect rgb(246, 239, 255)
            T->>API: POST /orders/send
            API->>R: submit via OneClickRouter
        end
    end
    R->>R: placeMarketOrder sell quantity
    R->>Stock: Lock max stock quantity
    TS->>TS: Execute at best available price
    TS->>Stock: Apply filled and unfilled result
    TS->>C: Credit mUSD proceeds
```

Market sell input is `quantity`: the maximum stock quantity to sell. `Stock` locks that quantity first; settlement applies only the filled amount and returns any unfilled stock to `Stock.stockBalance`.

## Place A Limit Order

```mermaid
sequenceDiagram
    participant T as Client
    participant API as Trading API
    participant R as StockRouter
    participant S as Stock
    participant C as Cashier
    participant B as Backend bots

    alt Self-submit
        rect rgb(232, 244, 255)
            T->>API: POST /orders/calldata
            T->>R: submit returned calldata
        end
    else One Click
        rect rgb(246, 239, 255)
            T->>API: POST /orders/send
            API->>R: submit via OneClickRouter
        end
    end
    R->>S: placeLimitOrder
    alt Buy
        S->>C: Lock mUSD
    else Sell
        S->>S: Lock stockBalance
    end
    B->>B: Execute when market conditions match
    alt Filled or partial
        B->>C: Apply mUSD spend/refund
        B->>S: Apply stock fill/remainder
    else Open
        B-->>API: Keep order in openOrder
    else Cancel
        T->>API: DELETE /orders/{orderId}/calldata or /send
        API->>R: cancelLimitOrder
        B->>C: Refund locked mUSD if needed
        B->>S: Return locked stock if needed
    end
```

Limit orders have a `price`, `quantity`, and `timeInForce`. Current production contracts accept only `DAY`; backend processing and settlement handle the practical lifecycle after placement.

Treat a limit order as an open commitment that locks `mUSD` or stock until fill, cancel, expiry, or settlement. Keep it separate from final portfolio balances.

## Reconcile Order Finality

A mined transaction means the order was accepted on-chain; it does not mean execution and settlement are final. Watch both mapping state and order detail:

1. `POST /api/v1/orders/tx` records a self-submitted tx.
2. `GET /api/v1/orders/tx/{txHash}` finds the tx mapping.
3. The indexer backfills `orderId`.
4. `GET /api/v1/orders/{orderId}` tracks open or historical state.
5. Portfolio balances update after settlement.

An order is economically final only after settlement updates `mUSD` and `exchangeBalance`.

## Understand Instant Vs Queued Cash

```mermaid
sequenceDiagram
    participant T as Client
    participant API as Trading API
    participant R as StockRouter
    participant C as Cashier
    participant B as Backend bots

    alt Self-submit
        rect rgb(232, 244, 255)
            T->>API: POST cash calldata endpoint
            T->>R: submit returned calldata
        end
    else One Click
        rect rgb(246, 239, 255)
            T->>API: POST cash send endpoint
            API->>R: submit via OneClickRouter
        end
    end
    R->>C: Record cash operation
    alt Buffer can cover operation
        C->>C: Apply mUSD credit or token payout
        API-->>T: operationStatus settled
    else Buffer cannot cover operation
        C->>C: Mark processing
        B->>B: Complete final cash settlement
        B->>C: Settle operation
        API-->>T: operationStatus settled
    end
```

Cash can be instant when buffers are available. Otherwise it is queued until final settlement completes. Track status with:

* `GET /api/v1/cash/deposits/{operationId}`
* `GET /api/v1/cash/withdrawals/{operationId}`

Handle both instant and queued outcomes. A queued operation is not necessarily failed; it may be waiting for final cash settlement.

The underlying contracts use two buffers: a global `creditBuffer` for instant deposits and a per-token `withdrawalBuffer` for instant withdrawals. Deposits and withdrawals can replenish each other's buffers. See [cash/buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism).

## Choose Execution Mode

Both modes call the same router methods. One Click only changes who submits the router transaction.

| Mode        | Use when                                           | Trade-off                                                |
| ----------- | -------------------------------------------------- | -------------------------------------------------------- |
| Self-submit | You manage wallets, custody, or transaction policy | More control; must record `txHash`                       |
| One Click   | You use delegated transaction submission           | Requires user delegation and API key bound `userAddress` |

Use Self-submit when your integration owns transaction policy or custody. Use One Click when the integration needs delegated submission after explicit authorization.

## Treat API Calldata As A Router Instruction

For self-submit, use `toAddress`, `value`, and `callData` exactly as returned by the API. Do not reconstruct calldata by hand unless you are deliberately bypassing the partner API. The API output is already shaped for the correct router method and product context.

## Pre-Trade Checklist

Before placing an order, confirm:

* Symbol is tradable for the selected chain/product.
* `x-api-chain-id`, wallet network, and `x-api-p` match.
* Portfolio has been refreshed.
* Plain buys use `mUsdBalance`; plain sells use `exchangeBalance`.
* Order-with-deposit flows require token allowance and, for buys, instant deposit availability.
* Deposit allowance is sufficient if funding is required.
* Execution mode is selected.
* Self-submit flows record `txHash`; One Click flows have `/1ct/status = enable`.

If a trade fails or appears stuck, check these in order: API response `code`, tx receipt, `/orders/tx/{txHash}`, `/orders/{orderId}`, then portfolio balances.

## Related Docs

| Need                             | Doc                                                                                                                                  |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| First API trade flow             | [../guides/quickstart-first-trade.md](/trading-api/guides/quickstart-first-trade)                                                    |
| How do I authenticate?           | [authenticate/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/authenticate/README.md) |
| How do I read balances?          | [portfolio/overview.md](/trading-api/portfolio/overview)                                                                             |
| How do I deposit?                | [cash/deposits.md](/trading-api/cash-operations/deposits)                                                                            |
| How do I place or cancel orders? | [trading/place-and-cancel-orders.md](/trading-api/trading/place-and-cancel-orders)                                                   |
| How do I track status?           | [trading/order-status-and-history.md](/trading-api/trading/order-status-and-history)                                                 |
| How do I submit with viem?       | [guides/demo-code.md](/trading-api/guides/demo-code)                                                                                 |
| How do I debug issues?           | [../reference/troubleshooting.md](/trading-api/reference/troubleshooting)                                                            |


# Headers & Permissions

## Required headers

All `/api/v1/**` endpoints require:

| Header           | Required | Description                                             |
| ---------------- | -------- | ------------------------------------------------------- |
| `x-api-key`      | Yes      | Partner API key.                                        |
| `x-api-ts`       | Yes      | Unix ms timestamp. ≤ **45 seconds** drift from UTC.     |
| `x-api-nonce`    | Yes      | Unique per key within the 45s window. UUID recommended. |
| `x-api-sign`     | Yes      | HMAC-SHA256 authentication value. Case-insensitive hex. |
| `x-api-chain-id` | Yes      | Chain ID for this request.                              |
| `x-api-p`        | Yes      | Product type for this request.                          |

## Supported chain IDs

| Value      | Chain            |
| ---------- | ---------------- |
| `8453`     | Base Mainnet     |
| `1`        | Ethereum Mainnet |
| `143`      | Monad Mainnet    |
| `11155111` | Ethereum Sepolia |
| `10143`    | Monad Testnet    |
| `84532`    | Base Sepolia     |

## Supported product types

| Value      | Description       |
| ---------- | ----------------- |
| `Anchored` | Anchored product. |

> Enum values are case-sensitive. These docs focus the Anchored RWA API; use `x-api-p: Anchored`.

## API key validation

| Check        | Rule                                                                                                                               |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| API key      | Must exist and be `active`.                                                                                                        |
| Expiry       | `expires_at` null or in the future.                                                                                                |
| IP whitelist | **Required — an empty whitelist rejects every request (`401`); it does not mean "no restriction".** Exact IP match only (no CIDR). |
| Scope        | Must match `chainId + productType + access`.                                                                                       |

> **Before your first request, add your egress IP to the key's whitelist.** A key with an empty/unset whitelist rejects *all* requests with `401 Unauthorized` — the single most common first-integration failure. Behind a gateway/proxy the server matches the IP it resolves (see below, usually the `X-Forwarded-For` value), not your machine's local IP.

### Client IP resolution

1. First non-empty IP in `X-Forwarded-For`
2. `X-Real-IP`
3. TCP `remoteAddr`

## Permission levels

| access      | Allowed operations       |
| ----------- | ------------------------ |
| `READ_ONLY` | `GET` only.              |
| `WRITABLE`  | `GET`, `POST`, `DELETE`. |


# HMAC Authentication

This page describes API request authentication. It is not wallet signing. Every private endpoint request must include an HMAC value in `x-api-sign`.

## Authentication payload

Five lines joined by `\n`:

```
METHOD
URI
TIMESTAMP
NONCE
RAW_BODY
```

| Field       | Description                                               |
| ----------- | --------------------------------------------------------- |
| `METHOD`    | Uppercase HTTP method.                                    |
| `URI`       | Path with sorted query string. No domain or context path. |
| `TIMESTAMP` | Same as `x-api-ts` (ms).                                  |
| `NONCE`     | Same as `x-api-nonce`.                                    |
| `RAW_BODY`  | Raw body string, or empty if none.                        |

## Query string sorting

Parameters sorted by name ascending. Example request:

```
GET /api/v1/orders?page=1&limit=10
```

Authenticated `URI`:

```
/api/v1/orders?limit=10&page=1
```

> Avoid duplicate query parameter names when building the authentication payload.

## Body authentication

JSON requests use `Content-Type: application/json`. `RAW_BODY` must match the sent body exactly (spaces, field order).

`GET` and bodyless `POST` use empty `RAW_BODY`.

## HMAC-SHA256

```
x-api-sign = hex(HMAC_SHA256(authenticationPayload, apiSecret))
```

UTF-8 encoding throughout.

### Python

```python
import hmac
import hashlib
from urllib.parse import urlencode

def canonical_uri(path: str, query: dict = None) -> str:
    if not query:
        return path
    sorted_pairs = sorted(query.items(), key=lambda x: x[0])
    return f"{path}?{urlencode(sorted_pairs)}"

def sign_trading_api(
    method: str,
    path: str,
    query: dict = None,
    timestamp: int = None,
    nonce: str = None,
    raw_body: str = "",
    api_secret: str = "",
) -> str:
    import time
    import uuid
    timestamp = timestamp or int(time.time() * 1000)
    nonce = nonce or str(uuid.uuid4())
    uri = canonical_uri(path, query)
    payload = f"{method.upper()}\n{uri}\n{timestamp}\n{nonce}\n{raw_body}"
    return hmac.new(
        api_secret.encode("utf-8"),
        payload.encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()
```

### cURL

cURL + openssl works for a quick check, but shell HMAC has sharp edges (trailing-newline stripping by `$(...)`, secrets starting with `-`, `date +%s%3N` on macOS/BSD, `PATH` clobbering). For production, prefer the Python example above or the Node `crypto` version in [examples.md](/trading-api/authentication/examples).

```bash
METHOD="GET"
URI="/api/v1/symbols"
# Unix milliseconds. GNU date works directly; BSD (macOS) date emits a literal "N",
# so fall back based on whether the output is all digits (do NOT rely on exit code —
# BSD date exits 0 even for %3N).
TIMESTAMP=$(date +%s%3N)
case "$TIMESTAMP" in
  ''|*[!0-9]*)
    if command -v gdate >/dev/null 2>&1; then TIMESTAMP=$(gdate +%s%3N)
    else TIMESTAMP=$(python3 -c 'import time; print(int(time.time()*1000))'); fi ;;
esac
NONCE=$(uuidgen | tr '[:upper:]' '[:lower:]')
RAW_BODY=""
# Pipe printf STRAIGHT into openssl. Three gotchas this avoids:
#  1) Join with REAL newlines (printf format), not the two-character "\n".
#  2) PAYLOAD=$(printf ...) would strip the trailing newline -> wrong sig for empty-body (GET/DELETE) requests.
#  3) -macopt "key:..." (not -hmac "...") so a secret starting with "-" isn't parsed as an openssl option.
HMAC_AUTH=$(printf '%s\n%s\n%s\n%s\n%s' "$METHOD" "$URI" "$TIMESTAMP" "$NONCE" "$RAW_BODY" \
  | openssl dgst -sha256 -mac HMAC -macopt "key:$API_SECRET" -hex | awk '{print $NF}')

curl -X GET "https://rwa-api.anchored.finance/rwa/trading/api/v1/symbols" \
  -H "x-api-key: ${API_KEY}" \
  -H "x-api-ts: ${TIMESTAMP}" \
  -H "x-api-nonce: ${NONCE}" \
  -H "x-api-sign: ${HMAC_AUTH}" \
  -H "x-api-chain-id: 8453" \
  -H "x-api-p: Anchored"
```


# Examples

Node.js HMAC authentication snippets. For a full integration sample with **viem** (self-submit tx, ERC-20 approve, One Click `signTypedData`), see [guides/demo-code.md](/trading-api/guides/demo-code).

## HMAC helper

```js
import crypto from "node:crypto";

function canonicalUri(path, query = {}) {
  const pairs = [];
  for (const key of Object.keys(query).sort()) {
    const value = query[key];
    if (Array.isArray(value)) {
      for (const item of value) pairs.push(`${key}=${item}`);
    } else if (value !== undefined && value !== null) {
      pairs.push(`${key}=${value}`);
    }
  }
  return pairs.length === 0 ? path : `${path}?${pairs.join("&")}`;
}

function signTradingApi({ method, path, query, timestamp, nonce, rawBody, apiSecret }) {
  const uri = canonicalUri(path, query);
  const payload = [
    method.toUpperCase(),
    uri,
    String(timestamp),
    nonce,
    rawBody ?? ""
  ].join("\n");

  return crypto
    .createHmac("sha256", apiSecret)
    .update(payload, "utf8")
    .digest("hex");
}
```

## Signed POST example

```js
const body = JSON.stringify({
  stockAddress: "0x0000000000000000000000000000000000000001",
  side: "Buy",
  type: "Market",
  notional: "10",
  deadline: 1893456000
});

const timestamp = Date.now();
const nonce = crypto.randomUUID();
const hmacAuth = signTradingApi({
  method: "POST",
  path: "/api/v1/orders/calldata",
  query: {},
  timestamp,
  nonce,
  rawBody: body,
  apiSecret: process.env.TRADING_API_SECRET
});

const headers = {
  "content-type": "application/json",
  "x-api-key": process.env.TRADING_API_KEY,
  "x-api-ts": String(timestamp),
  "x-api-nonce": nonce,
  "x-api-sign": hmacAuth,
  "x-api-chain-id": "8453",
  "x-api-p": "Anchored"
};

const response = await fetch(
  "https://rwa-api.anchored.finance/rwa/trading/api/v1/orders/calldata",
  { method: "POST", headers, body }
);
```

## cURL with HMAC

```bash
API_KEY="your-api-key"
API_SECRET='your-api-secret'   # single-quote it: a secret containing shell metacharacters breaks when double-quoted or sourced
METHOD="POST"
URI="/api/v1/orders/calldata"   # do NOT name this variable PATH — it clobbers the shell's $PATH
# Unix milliseconds. GNU date works directly; BSD (macOS) date emits a literal "N",
# so fall back based on whether the output is all digits (do NOT rely on exit code —
# BSD date exits 0 even for %3N).
TIMESTAMP=$(date +%s%3N)
case "$TIMESTAMP" in
  ''|*[!0-9]*)
    if command -v gdate >/dev/null 2>&1; then TIMESTAMP=$(gdate +%s%3N)
    else TIMESTAMP=$(python3 -c 'import time; print(int(time.time()*1000))'); fi ;;
esac
NONCE=$(uuidgen | tr '[:upper:]' '[:lower:]')
BODY='{"stockAddress":"0x0000000000000000000000000000000000000001","side":"Buy","type":"Market","notional":"10","deadline":1893456000}'

# Pipe printf STRAIGHT into openssl. Gotchas this avoids:
#  1) Join with REAL newlines (printf format), not the two-character "\n".
#  2) PAYLOAD=$(printf ...) would strip the trailing newline (breaks empty-body GET/DELETE).
#  3) -macopt "key:..." (not -hmac "...") so a secret starting with "-" isn't parsed as an option.
HMAC_AUTH=$(printf '%s\n%s\n%s\n%s\n%s' "$METHOD" "$URI" "$TIMESTAMP" "$NONCE" "$BODY" \
  | openssl dgst -sha256 -mac HMAC -macopt "key:$API_SECRET" -hex | awk '{print $NF}')

curl -X ${METHOD} "https://rwa-api.anchored.finance/rwa/trading${URI}" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${API_KEY}" \
  -H "x-api-ts: ${TIMESTAMP}" \
  -H "x-api-nonce: ${NONCE}" \
  -H "x-api-sign: ${HMAC_AUTH}" \
  -H "x-api-chain-id: 143" \
  -H "x-api-p: Anchored" \
  -d "${BODY}"
```

See also [signature.md](/trading-api/authentication/signature) for Python and HMAC authentication details, and [guides/demo-code.md](/trading-api/guides/demo-code) for viem integration.


# Holdings & Positions

Use these endpoints to monitor a user's `mUSD`, wallet token balances, and `exchangeBalance`.

`userId` is currently the user's wallet address (trimmed, lowercased).

For API-level interpretation of `mUsdBalance`, `walletBalance`, and `exchangeBalance`, read [getting-started/trader-questions.md](/trading-api/getting-started/trader-questions).

## Endpoints

| Method | Path                               | Description             |
| ------ | ---------------------------------- | ----------------------- |
| `GET`  | `/api/v1/users/{userId}`           | User info               |
| `GET`  | `/api/v1/users/{userId}/balance`   | Cash and token balances |
| `GET`  | `/api/v1/users/{userId}/positions` | Stock positions         |

## Query user info

```
GET /api/v1/users/{userId}
```

Response `data`:

| Field         | Type   | Description               |
| ------------- | ------ | ------------------------- |
| `userId`      | string | User ID (wallet address). |
| `userAddress` | string | Wallet address.           |

## Query balances

```
GET /api/v1/users/{userId}/balance
```

| Parameter        | Type   | Required | Default       | Description                  |
| ---------------- | ------ | -------- | ------------- | ---------------------------- |
| `spenderAddress` | string | No       | `0x000...000` | Spender for allowance query. |

Response `data`:

| Field           | Type   | Description   |
| --------------- | ------ | ------------- |
| `chainId`       | number | Chain ID.     |
| `productType`   | string | Product type. |
| `address`       | string | User wallet.  |
| `mUsdBalance`   | string | `mUSD`.       |
| `tokenBalances` | array  | Token list.   |

### tokenBalances item

| Field             | Type          | Description                                            |
| ----------------- | ------------- | ------------------------------------------------------ |
| `address`         | string        | Token address.                                         |
| `name`            | string        | Token name.                                            |
| `symbol`          | string        | Token symbol.                                          |
| `stockSymbol`     | string / null | Stock symbol (stock tokens).                           |
| `isStock`         | boolean       | Stock token flag.                                      |
| `decimals`        | number        | Decimals.                                              |
| `price`           | number / null | Price (stock tokens).                                  |
| `walletBalance`   | string        | Wallet balance (human-readable).                       |
| `walletAllowance` | string        | Allowance to spender.                                  |
| `exchangeBalance` | string        | API view of `Stock.stockBalance`; used by plain sells. |
| `logoUrl`         | string        | Logo URL.                                              |

## Query positions

```
GET /api/v1/users/{userId}/positions
```

Same query parameters as `/balance`. Returns `data` as a `tokenBalances` array.

Use `spenderAddress` when checking deposit allowance — see [cash/deposits.md](/trading-api/cash-operations/deposits).


# On-Chain Market Config

## Get market config

```
GET /api/v1/config
```

Returns on-chain exchange configuration for the current `chainId + productType` scope: cashier buffers, exchange fee settings, and per-token cashier limits/rates.

Permission: `READ_ONLY`. No query parameters.

This endpoint is separate from direct on-chain stock reference-price reads. For the `StockOracle` contract interface, see [Stock Oracle](/trading-api/market-data/stock-oracle).

## Response

Standard envelope. `data` contains:

| Field                | Type   | Description                                                    |
| -------------------- | ------ | -------------------------------------------------------------- |
| `cashierBuffer`      | object | Cashier-level buffer snapshot for instant deposit eligibility. |
| `exchangeFeeConfig`  | object | Exchange fee and minimum order settings.                       |
| `cashierTokenConfig` | object | Map of lowercase token address → per-token cashier config.     |

### Field naming note

`cashierBuffer` and each `cashierTokenConfig` entry use `chain`. `exchangeFeeConfig` uses `chainId`. Both represent the scoped chain ID.

### Value encoding

| Area                                                                 | Format                                | Example                                   |
| -------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------- |
| `cashierBuffer.creditBuffer`, `creditBufferCapacity`, `totalBalance` | Raw WAD integer strings (18 decimals) | `"743810467000000000000"` ≈ 743.81 `mUSD` |
| `cashierTokenConfig.withdrawalBuffer`, `withdrawalBufferCapacity`    | Raw integer strings in token decimals | `"253689533"` with `decimals: 6`          |
| `exchangeFeeConfig.mintFeeRate`, `protocolFeeRate`, `minOrderValue`  | Human-readable decimal strings        | `"0"`, `"0.001"`                          |
| `cashierTokenConfig.depositRate`, `withdrawalRate`                   | Human-readable decimal strings        | `"1"`, `"0.9969"`                         |

Do not parse WAD or token-amount fields as human-readable decimals.

### `cashierBuffer`

| Field                     | Type   | Description                                                                                                                                                          |
| ------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`                   | number | Chain ID for the scoped context.                                                                                                                                     |
| `productType`             | string | Product type, e.g. `Anchored`.                                                                                                                                       |
| `address`                 | string | Cashier contract address. Matches `cashierAddress` in `cashierTokenConfig` entries.                                                                                  |
| `instantThresholdDivisor` | string | Divisor used to cap instant operation size relative to buffer capacity. See [buffer mechanism — Instant Eligibility](/trading-api/cash-operations/buffer-mechanism). |
| `creditBuffer`            | string | Current `mUSD` credit buffer balance (WAD).                                                                                                                          |
| `creditBufferCapacity`    | string | Maximum `mUSD` credit buffer capacity (WAD).                                                                                                                         |
| `totalBalance`            | string | Total cashier balance snapshot (WAD).                                                                                                                                |

Per-token `withdrawalBuffer` values live under `cashierTokenConfig`, not in this object.

### `exchangeFeeConfig`

| Field             | Type   | Description                                                                                               |
| ----------------- | ------ | --------------------------------------------------------------------------------------------------------- |
| `chainId`         | number | Chain ID.                                                                                                 |
| `productType`     | string | Product type.                                                                                             |
| `mintFeeRate`     | string | Mint fee rate, human-readable (e.g. `0.001` = 0.1%). `"0"` means no mint fee.                             |
| `protocolFeeRate` | string | Protocol fee rate, human-readable. `"0"` means no protocol fee.                                           |
| `minOrderValue`   | string | Minimum order notional in USD, human-readable (e.g. `"1.00"`). `"0"` means no minimum enforced in config. |
| `txHash`          | string | Tx hash of the latest on-chain config update. May be empty when no update tx is recorded.                 |
| `updatedAt`       | number | Unix seconds when config was last updated.                                                                |

Use `minOrderValue`, `mintFeeRate`, and `protocolFeeRate` when validating or displaying order economics before calling order endpoints.

### `cashierTokenConfig` entries

Map keys are lowercase ERC-20 token addresses. Each value includes:

| Field                      | Type    | Description                                                             |
| -------------------------- | ------- | ----------------------------------------------------------------------- |
| `chain`                    | number  | Chain ID.                                                               |
| `productType`              | string  | Product type.                                                           |
| `cashierAddress`           | string  | Cashier contract address.                                               |
| `tokenAddress`             | string  | ERC-20 token address.                                                   |
| `minAmount`                | string  | Minimum deposit/withdraw amount in whole tokens.                        |
| `decimals`                 | number  | Token decimals.                                                         |
| `depositPaused`            | boolean | Deposit flow paused for this token.                                     |
| `withdrawPaused`           | boolean | Withdraw flow paused for this token.                                    |
| `depositRate`              | string  | Deposit rate, human-readable (e.g. `1` = no fee).                       |
| `withdrawalRate`           | string  | Withdrawal rate, human-readable (e.g. `0.9969`).                        |
| `withdrawalBuffer`         | string  | Current on-chain token buffer for instant withdrawals (token decimals). |
| `withdrawalBufferCapacity` | string  | Maximum token buffer capacity for instant withdrawals (token decimals). |

Check `depositPaused`, `withdrawPaused`, and buffer fields before building deposit or withdrawal calldata. See [cash deposits](/trading-api/cash-operations/deposits) and [withdrawals](/trading-api/cash-operations/withdrawals).

## Integration notes

* For instant vs queued cash behavior, pair buffer fields here with [buffer mechanism](/trading-api/cash-operations/buffer-mechanism).

Example payload: [sample-responses.md — Market config](/trading-api/reference/sample-responses).


# Stock Oracle

## Contract Overview

`StockOracle` stores one latest price payload per supported `bytes32 priceId`. The same oracle proxy can serve all stock symbols on a chain; it does not deploy one feed contract per symbol.

The oracle supports:

* single and batch price reads
* freshness-checked reads
* session-aware payloads
* bid and ask values alongside the main oracle price

All price fields use `8` decimals.

## Deployment and Backend Enablement

The integration draft records the intended mainnet proxy address as the same deterministic address on Ethereum, Monad, and Base:

| Network  | Chain ID | StockOracle proxy                            |
| -------- | -------: | -------------------------------------------- |
| Ethereum |      `1` | `0x037848af338c38e1e0ab722be80bf4c2e612a1f7` |
| Monad    |    `143` | `0x037848af338c38e1e0ab722be80bf4c2e612a1f7` |
| Base     |   `8453` | `0x037848af338c38e1e0ab722be80bf4c2e612a1f7` |

The draft also records implementation address `0x8745912828473e9bef9d843ce8629bee3dcb9fec` for reference only. Consumers should integrate with the proxy address, not the implementation address.

## Price IDs

Each supported asset is identified by `bytes32 priceId`.

The standard derived ID is:

```
priceId = keccak256(uppercase(trim(symbol)))
```

For example, the backend derives `AAPL` from the uppercase symbol bytes. Deployment scripts may also accept an explicit `bytes32 priceId`; if omitted, they use the same uppercase-symbol derivation.

Before reading a price, consumers can check:

```solidity
function isSupportedPriceId(bytes32 priceId) external view returns (bool);
function hasPrice(bytes32 priceId) external view returns (bool);
function description(bytes32 priceId) external view returns (string memory);
```

`isSupportedPriceId=true` means the ID is registered. `hasPrice=true` means at least one price has been published.

## Price Payload

Oracle reads return:

```solidity
enum Session {
    UNKNOWN,
    PRE_MARKET,
    REGULAR,
    POST_MARKET,
    OVERNIGHT,
    CLOSED
}

struct PricePayload {
    int128 price;
    int128 bestBid;
    int128 bestAsk;
    uint64 feedUpdateTimestamp;
    uint64 publishedAt;
    uint80 roundId;
    Session session;
}
```

| Field                 | Meaning                                                                 |
| --------------------- | ----------------------------------------------------------------------- |
| `price`               | Main oracle price, 8 decimals. Backend currently uses bid/ask midpoint. |
| `bestBid`             | Best bid price, 8 decimals.                                             |
| `bestAsk`             | Best ask price, 8 decimals.                                             |
| `feedUpdateTimestamp` | Source quote timestamp, in Unix seconds. Use this for freshness.        |
| `publishedAt`         | On-chain publish timestamp for this oracle round, in Unix seconds.      |
| `roundId`             | Monotonic oracle update round for this `priceId`.                       |
| `session`             | Market session associated with the source quote.                        |

Consumers should use `feedUpdateTimestamp` for staleness checks. `publishedAt` only says when the payload was written on-chain.

## Read APIs

Single-asset reads:

```solidity
function latestPrice(bytes32 priceId)
    external
    view
    returns (PricePayload memory);

function latestPriceNoOlderThan(bytes32 priceId, uint64 maxAge)
    external
    view
    returns (PricePayload memory);
```

Batch reads:

```solidity
function latestPrices(bytes32[] calldata priceIds)
    external
    view
    returns (PricePayload[] memory);

function latestPricesNoOlderThan(bytes32[] calldata priceIds, uint64 maxAge)
    external
    view
    returns (PricePayload[] memory);
```

Prefer `latestPriceNoOlderThan` or `latestPricesNoOlderThan` when the consuming contract must fail closed on stale source data. `maxAge` is denominated in seconds.

Current backend feeder comments note that the source quote can be about 15 minutes delayed. With the default 10-minute heartbeat, a consumer using `latestPriceNoOlderThan(maxAge)` should choose a `maxAge` that accounts for feed delay plus heartbeat and integration-specific risk tolerance; 25 minutes / 1500 seconds is a practical lower-bound example before adding any product-specific buffer.

## Read-Side Reverts

| Error               | Meaning                                                      |
| ------------------- | ------------------------------------------------------------ |
| `PriceIdNotFound`   | The `priceId` is not registered.                             |
| `PriceNotAvailable` | The `priceId` is registered but no price has been published. |
| `PriceTooOld`       | `block.timestamp - feedUpdateTimestamp > maxAge`.            |

## Write-Side Constraints

The backend feeder and deployment scripts are expected to satisfy these constraints before publishing:

| Constraint       | Contract behavior                                                                                                                                                    |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Registering IDs  | `registerPriceId` and `batchRegisterPriceIds` require `DEFAULT_ADMIN_ROLE`.                                                                                          |
| Updating prices  | `updatePrice` and `batchUpdatePrice` require `OPERATOR_ROLE`.                                                                                                        |
| Price validity   | `price`, `bestBid`, and `bestAsk` must be positive and fit into `int128`.                                                                                            |
| Spread validity  | `bestBid` cannot exceed `bestAsk`.                                                                                                                                   |
| Source timestamp | `feedUpdateTimestamp` cannot be in the future and cannot roll back below the current on-chain value.                                                                 |
| Same timestamp   | If `feedUpdateTimestamp` equals the current on-chain timestamp, the update is allowed only for a `CLOSED` carried-forward update with unchanged price, bid, and ask. |

These details are mainly useful for debugging feeder reverts and operational incidents. Normal readers do not need write permissions.

## Session Handling

Consumers should treat `session` as part of the risk model, not just display metadata.

Regular-session prices are generally the most liquid. Pre-market, post-market, and overnight prices may have wider spreads or lower coverage. `CLOSED` means the oracle carried forward the latest on-chain price into a closed-market state; it should not be treated the same as an active quote unless the integration explicitly supports that behavior.

For lending or risk-sensitive integrations, define per-asset and per-session controls for:

* maximum accepted age
* accepted spread or spread-derived haircut
* whether `CLOSED` prices are allowed
* fallback behavior when `PriceIdNotFound`, `PriceNotAvailable`, or `PriceTooOld` occurs


# Symbols & Tradability

## List tradable symbols

```
GET /api/v1/symbols
```

Returns `data` array items:

| Field                 | Type    | Description                          |
| --------------------- | ------- | ------------------------------------ |
| `symbol`              | string  | Stock symbol, e.g. `AAPL`.           |
| `contractAddress`     | string  | On-chain token address.              |
| `contractSymbol`      | string  | Contract symbol.                     |
| `contractName`        | string  | Contract name.                       |
| `decimals`            | number  | Contract decimals.                   |
| `onChainDecimals`     | number  | On-chain decimals.                   |
| `tradable`            | boolean | Tradable flag.                       |
| `fractionable`        | boolean | Fractional shares supported.         |
| `overnightTradable`   | boolean | Overnight session supported.         |
| `fractionalEhEnabled` | boolean | Fractional extended-hours supported. |
| `price`               | number  | Latest price.                        |
| `change24H`           | number  | 24h price change.                    |
| `change24HPercent`    | number  | 24h change percent.                  |
| `logoUrl`             | string  | Logo URL.                            |
| `lastUpdateTimestamp` | number  | Cache update (Unix seconds).         |
| `name`                | string  | Company name.                        |
| `pdfUrl`              | string  | Prospectus PDF URL.                  |
| `volume24H`           | number  | 24h volume.                          |

Use `contractAddress` as `stockAddress` when placing orders.

## Underlying stock quote

```
GET /api/v1/underlying/{symbol}/price
```

| Parameter | Type   | Description   |
| --------- | ------ | ------------- |
| `symbol`  | string | Stock symbol. |

Response fields (returned at the **top level** of `data`, not wrapped in a `basicInfo` object):

| Field                 | Type    | Description                  |
| --------------------- | ------- | ---------------------------- |
| `symbol`              | string  | Stock symbol.                |
| `contractAddress`     | string  | Token contract address.      |
| `contractSymbol`      | string  | Contract symbol.             |
| `onChainDecimals`     | number  | On-chain decimals.           |
| `name`                | string  | Company name.                |
| `exchange`            | string  | Exchange.                    |
| `status`              | string  | `active` or `inactive`.      |
| `price`               | number  | Latest price.                |
| `change24H`           | number  | 24h change.                  |
| `change24HPercent`    | number  | 24h change percent.          |
| `volume24H`           | number  | 24h volume.                  |
| `tradable`            | boolean | Tradable flag.               |
| `fractionable`        | boolean | Fractional shares.           |
| `lastUpdateTimestamp` | number  | Cache update (Unix seconds). |


# Quotes & History

## Real-time quote

```
GET /api/v1/prices/{symbol}
```

| Parameter | Type   | Description                                                         |
| --------- | ------ | ------------------------------------------------------------------- |
| `symbol`  | string | Stock symbol, token symbol, or token address. Uppercased by server. |

Response `data`:

| Field       | Type          | Description                                              |
| ----------- | ------------- | -------------------------------------------------------- |
| `basicInfo` | object        | Underlying quote (chain-agnostic).                       |
| `onChain`   | object / null | On-chain token info for current `chainId + productType`. |

For direct on-chain reference-price reads, see [Stock Oracle](/trading-api/market-data/stock-oracle).

## Historical K-line

```
GET /api/v1/prices/{symbol}/history
```

| Parameter    | Type   | Required | Default | Description                                    |
| ------------ | ------ | -------- | ------- | ---------------------------------------------- |
| `startTime`  | number | No       | —       | Start (Unix seconds).                          |
| `endTime`    | number | Yes      | —       | End (Unix seconds).                            |
| `interval`   | string | Yes      | —       | `1m`, `3m`, `5m`, `15m`, `1h`, `1d`, `1w`.     |
| `adjustment` | string | No       | `all`   | `raw`, `split`, `dividend`, `spin-off`, `all`. |
| `limit`      | number | No       | `100`   | Max bars. Server max `5000`.                   |

Bar fields:

| Field       | Type   | Description              |
| ----------- | ------ | ------------------------ |
| `open`      | number | Open.                    |
| `high`      | number | High.                    |
| `low`       | number | Low.                     |
| `close`     | number | Close.                   |
| `volume`    | number | Volume.                  |
| `timestamp` | number | Bar time (Unix seconds). |

## Corporate actions

```
GET /api/v1/corporate-action
```

Query stock corporate actions (splits, dividends, etc.) for planning and display.

| Parameter   | Type   | Required | Description                                                                  |
| ----------- | ------ | -------- | ---------------------------------------------------------------------------- |
| `symbol`    | string | Yes      | Stock symbol without `a` prefix, e.g. `AAPL`.                                |
| `startTime` | number | No       | Start filter (Unix seconds). Filters on action `time`.                       |
| `endTime`   | number | No       | End filter (Unix seconds). Filters on action `time`.                         |
| `types`     | array  | No       | Filter by corporate action type. Repeat param or comma-separated per client. |

Allowed `types`:

| Value             | Description     |
| ----------------- | --------------- |
| `reverse_splits`  | Reverse split.  |
| `forward_splits`  | Forward split.  |
| `unit_splits`     | Unit split.     |
| `stock_dividends` | Stock dividend. |
| `cash_dividends`  | Cash dividend.  |

Example:

```
GET /api/v1/corporate-action?symbol=AAPL&types=cash_dividends&startTime=1704067200
```

### Response

Standard envelope. `data` is an array of `BrokerCorporateAction` objects, newest first when filtered by time.

| Field         | Type   | Description                                            |
| ------------- | ------ | ------------------------------------------------------ |
| `symbol`      | string | Stock symbol.                                          |
| `type`        | string | One of the `types` values above.                       |
| `time`        | string | Action timestamp (ISO-8601 date-time).                 |
| `exDate`      | string | Ex-dividend or ex-split date.                          |
| `recordDate`  | string | Record date.                                           |
| `payableDate` | string | Payable date.                                          |
| `processDate` | string | Processing date.                                       |
| `info`        | object | Type-specific broker metadata. Shape varies by `type`. |

### `info` object (varies by type)

| Field                 | Typical for | Description              |
| --------------------- | ----------- | ------------------------ |
| `rate`                | dividends   | Dividend rate per share. |
| `special`             | dividends   | Special dividend flag.   |
| `cusip`               | dividends   | CUSIP identifier.        |
| `oldRate` / `newRate` | splits      | Split ratio components.  |

Example response:

```json
{
  "code": 200,
  "errMsg": "",
  "data": [
    {
      "symbol": "AAPL",
      "type": "cash_dividends",
      "time": "2024-05-10T00:00:00Z",
      "exDate": "2024-05-10",
      "recordDate": "2024-05-13",
      "payableDate": "2024-05-16",
      "processDate": "2024-05-16",
      "info": {
        "rate": 0.25,
        "special": false,
        "cusip": "037833100"
      }
    }
  ],
  "uuid": null,
  "t": null
}
```

> Schema: `BrokerCorporateAction` in [openapi.snapshot.json](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/reference/openapi.snapshot.json).


# Overview

Before placing orders, review the trader integration playbook in [getting-started/trader-questions.md](/trading-api/getting-started/trader-questions): tradable symbol, correct balance type, execution mode, and status tracking path.

## Order types

| Type        | Side            | Required fields                    |
| ----------- | --------------- | ---------------------------------- |
| Market buy  | `Buy`           | `notional`                         |
| Market sell | `Sell`          | `quantity`                         |
| Limit       | `Buy` or `Sell` | `quantity`, `price`, `timeInForce` |

All orders require `stockAddress` (from [symbols list](/trading-api/market-data/symbols-and-tradability)) and `deadline` (Unix seconds, ≤ `4294967295`).

> **Market orders (buy/sell, incl. deferred market sell) are accepted only during the regular US trading session.** Outside it (pre-market, after-hours, overnight, closed) they are rejected up front — use limit orders. Limit orders are unaffected. See [place-and-cancel-orders.md](/trading-api/trading/place-and-cancel-orders).

> Use **strings** for `quantity`, `notional`, and `price` to avoid JS precision loss.

**Deferred sell** (selling a stock before holding it, creating a repayable debt) is placed through these same order endpoints with `deferred: true` + `side: Sell` (whitelist-gated). See [deferred-sell.md](/trading-api/trading/deferred-sell).

## Execution modes

| Mode        | Place order             | Cancel limit                        | Record tx         |
| ----------- | ----------------------- | ----------------------------------- | ----------------- |
| Self-submit | `POST /orders/calldata` | `DELETE /orders/{orderId}/calldata` | `POST /orders/tx` |
| One Click   | `POST /orders/send`     | `DELETE /orders/{orderId}/send`     | Auto-recorded     |

One Click requires enabled delegation — see [one-click-delegated.md](/trading-api/trading/one-click-delegated) and [guides/one-click-flow.md](/trading-api/guides/one-click-flow).

## Typical flow

1. Check [portfolio](/trading-api/portfolio/overview) for buying power and holdings.
2. Get quote from [market](/trading-api/market-data/quotes-and-history) if needed.
3. Build or send order — [place-and-cancel-orders.md](/trading-api/trading/place-and-cancel-orders).
4. Track status — [order-status-and-history.md](/trading-api/trading/order-status-and-history).

Self-submit sequence: see [guides/self-submit-on-chain.md](/trading-api/guides/self-submit-on-chain).


# Place & Cancel Orders

## Build order calldata

```
POST /api/v1/orders/calldata
```

| Field          | Type            | Required    | Description                                                                                                                                                                                                                                               |
| -------------- | --------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stockAddress` | string          | Yes         | Stock token address (EVM).                                                                                                                                                                                                                                |
| `side`         | string          | Yes         | `Buy` or `Sell`.                                                                                                                                                                                                                                          |
| `type`         | string          | Yes         | `Market` or `Limit`.                                                                                                                                                                                                                                      |
| `quantity`     | string / number | Conditional | Limit orders; market sells.                                                                                                                                                                                                                               |
| `notional`     | string / number | Conditional | Market buys.                                                                                                                                                                                                                                              |
| `price`        | string / number | Conditional | Limit orders.                                                                                                                                                                                                                                             |
| `timeInForce`  | string          | Conditional | Limit orders. See [enums](/trading-api/reference/enums).                                                                                                                                                                                                  |
| `deadline`     | number          | Yes         | Tx deadline (Unix seconds).                                                                                                                                                                                                                               |
| `deferred`     | boolean         | No          | Deferred sell (sell-before-holding, debt-creating). Only valid with `side: Sell` and requires a whitelisted address. Routes to `deferredLimitSell`/`deferredMarketSell`. See [deferred-sell.md](/trading-api/trading/deferred-sell). Defaults to `false`. |

### Market buy

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "side": "Buy",
  "type": "Market",
  "notional": "10",
  "deadline": 1893456000
}
```

### Limit sell

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "side": "Sell",
  "type": "Limit",
  "quantity": "1.25",
  "price": "180.50",
  "timeInForce": "DAY",
  "deadline": 1893456000
}
```

### Limit buy

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "side": "Buy",
  "type": "Limit",
  "quantity": "0.05",
  "price": "180.50",
  "timeInForce": "DAY",
  "deadline": 1893456000
}
```

> Limit orders (**buy and sell**) use `quantity` + `price`; `notional` is only for **market buys**. Production limit orders accept only `timeInForce: "DAY"` — other values revert on-chain. **Market orders are accepted only during the regular US trading session.** Pre-market, after-hours, overnight and closed sessions reject with `market order is only supported during the regular trading session (current: <session>)`. This is enforced when building calldata, so it applies to both `/calldata` (self-submit) and `/send` (One Click). Use limit orders outside regular hours.

Response `data`:

| Field         | Type   | Description                              |
| ------------- | ------ | ---------------------------------------- |
| `chainId`     | number | Chain ID.                                |
| `productType` | string | Product type.                            |
| `toAddress`   | string | Router address.                          |
| `value`       | string | Native value (`"0"`).                    |
| `callData`    | string | Encoded calldata.                        |
| `method`      | string | `placeMarketOrder` or `placeLimitOrder`. |

Submit `toAddress` + `callData` on-chain, then record via [order-status-and-history.md](/trading-api/trading/order-status-and-history).

## One Click place order

```
POST /api/v1/orders/send
```

Same body as `/calldata`, plus optional `gasLimit` (set a buffer — the API broadcasts through `OneClickRouter` and pays gas). Requires One Click enabled and API key `userAddress` configured.

The response is the **order-tx mapping**, not calldata: `{ id, chainId, productType, operationType, orderId, txHash, status, ... }`. `orderId` is `null` until the indexer backfills it — poll `GET /orders/tx/{txHash}` or `GET /orders/{orderId}` (once populated).

## Build Order-With-Deposit Calldata

```
POST /api/v1/orders/with-deposit/calldata
```

Use this endpoint when the order transaction should also use `StockRouter` as the approved spender before placing the order. For buys, `StockRouter` transfers the cash token to `Cashier`; for sells, it transfers the stock token to `Stock`.

| Field                 | Type            | Required    | Description                                                                                                |
| --------------------- | --------------- | ----------- | ---------------------------------------------------------------------------------------------------------- |
| `stockAddress`        | string          | Yes         | Stock token address.                                                                                       |
| `depositAmount`       | string / number | Yes         | Human-readable deposit amount. For buys, this is cash token amount. For sells, this is stock token amount. |
| `depositTokenAddress` | string          | Conditional | Cash token address. Required for buy orders.                                                               |
| `side`                | string          | Yes         | `Buy` or `Sell`.                                                                                           |
| `type`                | string          | Yes         | `Market` or `Limit`.                                                                                       |
| `quantity`            | string / number | Conditional | Limit orders; market sells.                                                                                |
| `notional`            | string / number | Conditional | Market buys.                                                                                               |
| `price`               | string / number | Conditional | Limit orders.                                                                                              |
| `timeInForce`         | string          | Conditional | Limit orders.                                                                                              |
| `deadline`            | number          | Yes         | Tx deadline (Unix seconds).                                                                                |

For buy orders, the cash token must be approved for `StockRouter`, and the cash deposit must be eligible for instant deposit; otherwise the combined transaction reverts. For sell orders, the wallet stock token must be approved for `StockRouter`.

### Market buy with deposit

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "depositTokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "depositAmount": "100",
  "side": "Buy",
  "type": "Market",
  "notional": "10",
  "deadline": 1893456000
}
```

### Market sell with stock deposit

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "depositAmount": "1.25",
  "side": "Sell",
  "type": "Market",
  "quantity": "1.25",
  "deadline": 1893456000
}
```

## One Click Order With Deposit

```
POST /api/v1/orders/with-deposit/send
```

Same body as `/with-deposit/calldata`, plus optional `gasLimit`. Requires One Click enabled and API key `userAddress` configured.

## Cancel limit order

### Self-submit cancel calldata

```
DELETE /api/v1/orders/{orderId}/calldata?deadline=1893456000
```

> Use the `orderId` **exactly as returned by the API** — a `0x`-prefixed 32-byte hex string (66 characters), e.g. `0x00000000000049fb0001000049d0d92daa26b7f121276e7034af17aed9e4c71e`. Put it in the path as-is: `DELETE /api/v1/orders/0x00000000000049fb0001000049d0d92daa26b7f121276e7034af17aed9e4c71e/calldata?deadline=1893456000`

### One Click cancel

```
DELETE /api/v1/orders/{orderId}/send?deadline=1893456000
```

Returns `uuid` and `txHash`.

### Cancel rules

* Order belongs to current API key
* Order is open
* Limit orders only
* No pending cancel in flight
* API key `userAddress` matches order user


# Deferred Sell

Deferred sell lets a whitelisted partner place a sell order for a stock **without first depositing it into their exchange (sellable) balance**. The filled quantity becomes an on-chain **debt** that the partner must later repay by depositing the stock. It is a sell-now, deliver-later flow, distinct from a plain sell (which locks stock you already hold in your exchange balance).

All deferred-sell endpoints target `StockRouter`. The API surfaces the current debt per stock so integrators can track outstanding obligations.

## Access Control (Whitelist)

Placing a deferred sell is **whitelisted per address**. Your address must be enabled by the Anchored team before it can place a deferred sell — you do not configure this yourself. The API checks this **before** building calldata, so an address that is not permitted is rejected up front (e.g. `deferred sell is not allowed for this address`) instead of broadcasting a transaction that would revert on-chain.

The gate applies only to **placing** a deferred sell (`/orders/calldata` / `/orders/send` with `deferred: true`). Repaying debt is always allowed.

## Risk Control (Balance & Quantity Limits)

The whitelist above is the **first** gate — a synchronous, pre-placement check at the API. There is now a **second** gate: a **risk control** applied *after* the order is on-chain, while the indexer processes the `OrderPlaced` event. It runs only for **deferred sell** orders (`side = Sell`, `deferred = true`) and enforces two limits:

| # | Check                    | Rejected when                                                                                                                       | `brokerFailedReason`                                  |
| - | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| 1 | **Already holds enough** | The partner's current exchange balance for the stock is `>= quantity` — you don't need a deferred sell, place a plain sell instead. | `Stock balance is enough,can not use deferred order.` |
| 2 | **Sellable quantity**    | `quantity` exceeds the net amount the partner is allowed to defer-sell (see formula below).                                         | `Insufficient quantity to place deferred order.`      |

Check 1 runs first; if the partner has no balance record or holds less than `quantity`, it passes to check 2.

**Sellable quantity** is computed across the partner's **relation-address group** (see below), from indexed order state:

```
totalCanSell = totalBuy − totalSell − totalSelling

  totalBuy     = Σ filled_quantity of all BUY  orders in history
  totalSell    = Σ filled_quantity of all SELL orders in history
  totalSelling = Σ place_quantity  of current OPEN sell orders
```

i.e. a deferred sell is capped at the group's net-acquired position minus what is already resting on the sell side. A new deferred sell passes only if `totalCanSell >= quantity`.

### Relation-address group

Each deferred-sell config carries a `relation_address` list. `totalBuy` / `totalSell` / `totalSelling` are summed over **every address in that list**, so a partner operating several wallets has their buys, sells and open sells netted together into one limit. The list **defaults to just the partner's own address** and is provisioned by the Anchored team alongside the whitelist config.

### How a risk rejection surfaces (differs from the whitelist gate)

Because this gate runs *after* the on-chain placement, a deferred sell that fails risk control is **not** rejected at the API — the transaction is broadcast and the on-chain order is created normally. The rejection happens at the **broker step**:

* The order is marked internally as failing risk control (with the reason), and **is never routed to the broker**.
* A broker order is recorded directly as **`FAILED`**, its fail reason set to the reason string above (surfaced to integrators as `brokerFailedReason`).
* The on-chain order is then settled/cancelled.

So an integrator sees the order reach a **failed / cancelled** terminal state with `brokerFailedReason` populated — **not** an HTTP error at placement time. **Always confirm a deferred sell via order status** (see [Tracking a Deferred Sell Order](#tracking-a-deferred-sell-order)); a successful broadcast does not guarantee the order was placed at the broker.

## Place a Deferred Sell

A deferred sell is a regular sell order — it is placed through the **standard order endpoints** with `deferred: true`; there are no separate deferred placement endpoints.

```
POST /api/v1/orders/calldata   (self-submit)
POST /api/v1/orders/send       (One Click)
```

Same body as a normal order (see [place-and-cancel-orders.md](/trading-api/trading/place-and-cancel-orders)) plus `deferred: true`. Rules:

* `side` **must be `Sell`** — deferred is sell-only; `deferred` with `Buy` is rejected (`deferred is only supported for sell orders`).
* `type: Limit` → `quantity` + `price` + `timeInForce: "DAY"`; `type: Market` → `quantity`. No `notional`.
* The address must be whitelisted (see [Access Control](#access-control-whitelist)); a **market** deferred sell is only accepted during the regular US session.
* Even when whitelisted, the order must pass the balance & quantity **risk control** (see [Risk Control](#risk-control-balance--quantity-limits)) — this is checked after placement, so a failing order lands in a **FAILED** state with `brokerFailedReason` rather than being rejected at the API.

### Limit deferred sell

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "side": "Sell",
  "type": "Limit",
  "quantity": "1.25",
  "price": "180.50",
  "timeInForce": "DAY",
  "deadline": 1893456000,
  "deferred": true
}
```

### Market deferred sell

```json
{
  "stockAddress": "0x0000000000000000000000000000000000000001",
  "side": "Sell",
  "type": "Market",
  "quantity": "1.25",
  "deadline": 1893456000,
  "deferred": true
}
```

`/orders/calldata` returns calldata with `method` `deferredLimitSell` / `deferredMarketSell`. `/orders/send` returns the **order-tx mapping** (`operationType: "trade"`). The order is then tracked like any other order (with `deferred: true` on the response) — see [Tracking a Deferred Sell Order](#tracking-a-deferred-sell-order).

## Repay Deferred Sell Debt

```
POST /api/v1/deferred-sell/repay/calldata
```

| Field          | Type            | Required | Description                                                        |
| -------------- | --------------- | -------- | ------------------------------------------------------------------ |
| `stockAddress` | string          | Yes      | Stock token whose deferred-sell debt is repaid.                    |
| `amount`       | string / number | Yes      | Human-readable stock amount to repay against the outstanding debt. |

Response `data` is the standard calldata shape above; `method` is `repayDeferredStockDebt`.

> **Repay pulls the stock from the partner's wallet, not from `exchangeBalance`.** `repayDeferredStockDebt` does an ERC-20 `transferFrom(wallet → …)` and burns it, so before repaying you must:
>
> 1. Hold the stock token in the **wallet** — if it currently sits in `exchangeBalance` (e.g., just bought), withdraw it first via `POST /api/v1/stock/withdrawals/send`.
> 2. **Approve `StockRouter`** for the repay amount on the stock token (One Click does **not** perform the approval for you — it must be a wallet transaction).
>
> Missing either step reverts: no wallet balance / allowance → `ERC20InsufficientAllowance`; repaying more than the outstanding debt → `DeferredDebtExceeded`.

## One Click Repay

```
POST /api/v1/deferred-sell/repay/send
```

Same body as `/deferred-sell/repay/calldata`, plus optional `gasLimit`. Returns the order-tx mapping (`operationType: "deferred_repay"`). The wallet-balance and approval prerequisites above still apply.

## Query Deferred Sell Debts

```
GET /api/v1/deferred-sell/debts
GET /api/v1/deferred-sell/debts?stockAddress=0x0000000000000000000000000000000000000001
```

Returns the authenticated user's current outstanding deferred-sell debts from indexed state. Pass an optional `stockAddress` to filter to a single stock.

Response `data` is an array of:

| Field                 | Type            | Description                                          |
| --------------------- | --------------- | ---------------------------------------------------- |
| `stockAddress`        | string          | Stock token contract address.                        |
| `stockSymbol`         | string          | Stock symbol.                                        |
| `stockContractSymbol` | string          | Stock contract symbol.                               |
| `debt`                | string / number | Current outstanding debt in stock units.             |
| `lastUpdateTxHash`    | string          | Tx hash of the last debt change (fill or repayment). |
| `lastUpdateBlockTime` | string          | Block time of the last debt change.                  |

Debt increases as a deferred order fills and decreases on repayment. A stock with no outstanding debt is not returned.

## Tracking a Deferred Sell Order

A deferred sell **is a regular exchange order** (same order lifecycle, orderId, open/history tables), so it is tracked through the **standard order endpoints** — there are no deferred-specific order/tx query endpoints:

| Need                         | Endpoint                                              |
| ---------------------------- | ----------------------------------------------------- |
| List orders                  | `GET /api/v1/orders`                                  |
| Order detail (status + fill) | `GET /api/v1/orders/{orderId}`                        |
| Find order by tx             | `GET /api/v1/orders/tx/{txHash}`                      |
| Cancel                       | `DELETE /api/v1/orders/{orderId}/calldata` or `/send` |

These responses carry a **`deferred`** boolean (`true` for deferred sells) so you can distinguish them from plain sells. A deferred sell that was blocked by [risk control](#risk-control-balance--quantity-limits) reaches a **failed/cancelled** status with `brokerFailedReason` set to the reason string. See [order-status-and-history.md](/trading-api/trading/order-status-and-history).

The order-tx mapping for a deferred sell is recorded with `operationType: "trade"` (it is an order). Only **repay** uses a distinct `operationType: "deferred_repay"`, and repay is not an order (no `orderId`, not in the order tables), so it does not appear in `/orders`.

> Note: the current outstanding **debt** is not on the order object; read it from `GET /api/v1/deferred-sell/debts`.


# Order Status & History

## Record self-submitted order tx

```
POST /api/v1/orders/tx
```

| Field    | Type   | Required | Description                |
| -------- | ------ | -------- | -------------------------- |
| `txHash` | string | Yes      | On-chain transaction hash. |

Indexer backfills `orderId` from chain events.

> Same `txHash` from the same API key returns the existing mapping. A `txHash` already owned by another key returns an error.

## Query orders

### List mappings

```
GET /api/v1/orders?page=1&limit=10
```

### By tx hash

```
GET /api/v1/orders/tx/{txHash}
```

### By order ID

```
GET /api/v1/orders/{orderId}
```

`orderId` must belong to a mapping recorded by the current API key.

## Order detail fields

**Top level:**

| Field                | Type          | Description                                                                                                         |
| -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------- |
| `status`             | string        | Broker mapped order status.                                                                                         |
| `deferred`           | boolean       | `true` if this is a [deferred sell](/trading-api/trading/deferred-sell) (sell-before-holding, debt-creating) order. |
| `brokerFailedReason` | string        | Failure reason, when applicable.                                                                                    |
| `mapping`            | object        | Partner order-tx mapping.                                                                                           |
| `openOrder`          | object / null | Present while the order is open.                                                                                    |
| `historyOrder`       | object / null | Present once the order has settled.                                                                                 |

**openOrder:**

| Field           | Type   | Description                                                       |
| --------------- | ------ | ----------------------------------------------------------------- |
| `orderId`       | string | On-chain order ID.                                                |
| `userAddress`   | string | User address.                                                     |
| `side`          | string | `Buy` or `Sell`.                                                  |
| `type`          | string | `Market` or `Limit`.                                              |
| `tif`           | string | Time in force.                                                    |
| `symbol`        | string | Symbol.                                                           |
| `placeNotional` | string | Order notional (`0` for limit orders, which use `placeQuantity`). |
| `placeQuantity` | string | Order quantity.                                                   |
| `pay`           | string | Payment amount.                                                   |
| `placePrice`    | string | Order (limit) price.                                              |
| `status`        | string | `placing` or `canceling`.                                         |

**historyOrder** adds:

| Field           | Type          | Description      |
| --------------- | ------------- | ---------------- |
| `settleTxHash`  | string / null | Settlement tx.   |
| `settlePrice`   | string        | Execution price. |
| `settlePay`     | string / null | Actual payment.  |
| `settleReceive` | string / null | Actual received. |
| `mintFee`       | string        | Mint fee.        |
| `protocolFee`   | string        | Protocol fee.    |

See [reference/enums.md](/trading-api/reference/enums) for status values.


# One Click Delegated

One Click lets the server submit transactions via an authorized proxy wallet. Required before calling any `/send` endpoint.

For user-facing safety copy, signer checks, and delegation UX, read [one-click-security-ux.md](/trading-api/trading/one-click-security-ux).

## Query status

```
GET /api/v1/1ct/status
```

| Field       | Type   | Description                |
| ----------- | ------ | -------------------------- |
| `status`    | string | `/send` requires `enable`. |
| `delegatee` | string | Proxy wallet address.      |

## Prepare EIP-712 payload

```
POST /api/v1/1ct/prepare
```

| Field      | Type   | Required | Description                        |
| ---------- | ------ | -------- | ---------------------------------- |
| `deadline` | number | Yes      | Signature deadline (Unix seconds). |

Response `data`:

| Field         | Type   | Description         |
| ------------- | ------ | ------------------- |
| `delegatee`   | string | Proxy address.      |
| `signPayload` | object | EIP-712 typed data. |
| `nonce`       | number | Delegate nonce.     |
| `deadline`    | number | Same as request.    |

Example `signPayload`:

```json
{
  "domain": {
    "name": "OneClickRouter",
    "version": "1",
    "chainId": 10143,
    "verifyingContract": "0x..."
  },
  "types": {
    "Delegate": [
      { "name": "user", "type": "address" },
      { "name": "delegatee", "type": "address" },
      { "name": "nonce", "type": "uint64" },
      { "name": "deadline", "type": "uint32" }
    ]
  },
  "primaryType": "Delegate",
  "message": {
    "user": "0x...",
    "delegatee": "0x...",
    "nonce": 0,
    "deadline": 1893456000
  }
}
```

> The live `signPayload.types` also contains an `EIP712Domain` entry (omitted above for brevity). **ethers** ignores it — pass only `{ Delegate: ... }` as shown below. **viem** derives the domain itself and *throws* if `EIP712Domain` is present in `types`, so strip it first (see [guides/demo-code.md](/trading-api/guides/demo-code)).

## Enable

```
POST /api/v1/1ct/enable
```

| Field       | Type   | Required | Description                                  |
| ----------- | ------ | -------- | -------------------------------------------- |
| `signature` | string | Yes      | 65-byte hex EIP-712 signature (`0x` prefix). |
| `deadline`  | number | Yes      | Must match `/prepare` response.              |

### ethers v6 signing

```js
import { Wallet } from "ethers";

const { signPayload, deadline } = prepareResponse.data;
const wallet = new Wallet(process.env.USER_PRIVATE_KEY);

if (wallet.address.toLowerCase() !== signPayload.message.user.toLowerCase()) {
  throw new Error("signer address must match signPayload.message.user");
}

const signature = await wallet.signTypedData(
  { ...signPayload.domain, chainId: BigInt(signPayload.domain.chainId) },
  { Delegate: signPayload.types.Delegate },
  {
    ...signPayload.message,
    nonce: BigInt(signPayload.message.nonce),
    deadline: BigInt(signPayload.message.deadline),
  }
);
```

## Disable

```
POST /api/v1/1ct/disable
```

No body. Use empty string for HMAC `RAW_BODY`.

## Send endpoints after enable

| Operation                | Endpoint                           | Method |
| ------------------------ | ---------------------------------- | ------ |
| Place order              | `/api/v1/orders/send`              | POST   |
| Place order with deposit | `/api/v1/orders/with-deposit/send` | POST   |
| Cancel order             | `/api/v1/orders/{orderId}/send`    | DELETE |
| Cash deposit             | `/api/v1/cash/deposits/send`       | POST   |
| Cash withdrawal          | `/api/v1/cash/withdrawals/send`    | POST   |
| Stock deposit            | `/api/v1/stock/deposits/send`      | POST   |
| Stock withdrawal         | `/api/v1/stock/withdrawals/send`   | POST   |

Flow: build calldata internally → submit via One Click → auto-record tx on success.

See [guides/one-click-flow.md](/trading-api/guides/one-click-flow).


# One Click Security and API Semantics

One Click reduces repeated wallet prompts by letting a delegated service submit router transactions for a user. It does **not** change the underlying trading contracts: orders, deposits, withdrawals, and cancels still go through `StockRouter`.

## Mental Model

```mermaid
flowchart LR
    U[User wallet] -->|signs EIP-712 Delegate| API[Trading API]
    API -->|enable| OCR[OneClickRouter]
    D[Delegatee service] -->|execute as user| OCR
    OCR -->|ERC-2771 forward| R[StockRouter]
    R --> S[Cashier and Stock]
```

The user signs a typed delegation message. The delegatee service can then forward allowed router calls through `OneClickRouter`. The downstream router resolves the original user through ERC-2771 forwarding.

## Authorization Scope

Before enabling One Click, the integration should treat the delegation as a scoped transaction authorization:

* The delegatee can submit supported RWA trading router calls.
* The delegatee can place orders, cancel orders, deposit, and withdraw through allowed `/send` flows.
* The authorization is tied to the chain, OneClickRouter, delegatee, nonce, and deadline in the EIP-712 payload.
* Delegation can be disabled.

## API Flow

```mermaid
sequenceDiagram
    participant Client
    participant API as Trading API
    participant User
    participant OCR as OneClickRouter

    Client->>API: GET /1ct/status
    API-->>Client: status and delegatee
    Client->>API: POST /1ct/prepare
    API-->>Client: EIP-712 signPayload
    Client->>User: Request typed-data signature
    User-->>Client: signature
    Client->>API: POST /1ct/enable
    API->>OCR: delegateBySig
    API-->>Client: enabled
```

## Implementation Rules

| Rule                                            | Why                                                                      |
| ----------------------------------------------- | ------------------------------------------------------------------------ |
| Verify signer equals `signPayload.message.user` | Prevent enabling delegation for the wrong wallet                         |
| Use the returned `deadline` exactly             | It is part of the signed payload                                         |
| Treat nonce as single-use                       | Reusing old signatures should fail                                       |
| Check `/1ct/status` before `/send`              | Avoid avoidable send failures                                            |
| Keep `userAddress` binding explicit             | `/send` uses the API key bound user, not arbitrary request `userAddress` |
| Always support disable                          | Users need a clear recovery path                                         |

## API States

Treat One Click as a small API state machine: not enabled, preparing, signature requested, enabled, and disable pending. The only state that should allow `/send` endpoints is `Enabled`.

State mapping:

| State               | Integration handling                                       |
| ------------------- | ---------------------------------------------------------- |
| Not enabled         | Do not call `/send`; use `/calldata` or prepare delegation |
| Preparing           | Call `/1ct/prepare` and request typed-data signature       |
| Signature requested | Wait for a valid user signature                            |
| Enabled             | `/send` endpoints can be used                              |
| Disable pending     | Do not assume future `/send` requests will succeed         |

## Deposit Caveat

One Click does not remove ERC-20 approval requirements. For `/cash/deposits/send`, the API key bound `userAddress` must still approve the cash token spender.

## Risk Boundaries

One Click should be treated as a powerful trading authorization:

* Do not hide the delegatee address.
* Do not reuse signatures across chains or routers.
* Do not submit `/send` for a different user than the bound `userAddress`.
* Log `uuid`, `txHash`, and operation/order IDs for audit.

## Related Docs

| Need                   | Doc                                                                       |
| ---------------------- | ------------------------------------------------------------------------- |
| Endpoint details       | [one-click-delegated.md](/trading-api/trading/one-click-delegated)        |
| End-to-end flow        | [../guides/one-click-flow.md](/trading-api/guides/one-click-flow)         |
| viem typed-data sample | [../guides/demo-code.md](/trading-api/guides/demo-code)                   |
| Troubleshooting        | [../reference/troubleshooting.md](/trading-api/reference/troubleshooting) |


# Overview

Docs for deposits, withdrawals, and cash operation status.

| Need                              | Doc                                                                  |
| --------------------------------- | -------------------------------------------------------------------- |
| Understand instant vs queued cash | [buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism) |
| Deposit cash into `mUSD`          | [deposits.md](/trading-api/cash-operations/deposits)                 |
| Withdraw `mUSD` to tokens         | [withdrawals.md](/trading-api/cash-operations/withdrawals)           |
| Track deposit/withdraw status     | [operation-status.md](/trading-api/cash-operations/operation-status) |

API model: deposits turn wallet cash tokens into `mUsdBalance`; withdrawals turn `mUsdBalance` back into wallet cash tokens. Buffers only determine whether that happens instantly or after queued settlement.


# Deposits

Deposits turn wallet cash tokens into `mUSD` (`mUsdBalance`). See [getting-started/trader-questions.md](/trading-api/getting-started/trader-questions) for the API flow and the distinction between wallet balance and `mUSD`.

Deposits may complete instantly if the Cashier `creditBuffer` can cover the `mUSD` credit and the token withdrawal buffer has room. Otherwise they are queued for final cash settlement. See [buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism).

## Pre-authorization

Deposits transfer cash tokens from the user wallet to `Cashier` through `StockRouter`. The user must `approve` `StockRouter` as the spender before deposit:

```
ERC20(tokenAddress).approve(stockRouter, rawTokenAmount)
```

`rawTokenAmount = tokenAmount × 10^tokenDecimals`

### Mainnet cash token and approval spender addresses

| `x-api-chain-id` | Chain            | Cash token                                   | Approval spender (`StockRouter`)             |
| ---------------- | ---------------- | -------------------------------------------- | -------------------------------------------- |
| `8453`           | Base Mainnet     | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |
| `143`            | Monad Mainnet    | `0x754704Bc059F8C67012fEd69BC8A327a5aafb603` | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |
| `1`              | Ethereum Mainnet | `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |

Check allowance:

```
GET /api/v1/users/{userId}/balance?spenderAddress={spender}
```

Use `tokenBalances[].walletAllowance`.

> Insufficient allowance: `/cash/deposits/calldata` still returns calldata, but the on-chain tx will fail.

Approval owner:

* `/cash/deposits/send` (One Click): API key bound `userAddress`
* `/cash/deposits/calldata` (self-submit): transaction sender wallet

## Build deposit calldata

```
POST /api/v1/cash/deposits/calldata
```

| Field          | Type            | Required | Description              |
| -------------- | --------------- | -------- | ------------------------ |
| `userAddress`  | string          | Yes      | User wallet.             |
| `tokenAddress` | string          | Yes      | Cash token address.      |
| `tokenAmount`  | string / number | Yes      | Amount (human-readable). |

Returns `method: deposit`, `value: "0"`.

## One Click deposit

```
POST /api/v1/cash/deposits/send
```

| Field          | Type            | Required | Description         |
| -------------- | --------------- | -------- | ------------------- |
| `tokenAddress` | string          | Yes      | Cash token address. |
| `tokenAmount`  | string / number | Yes      | Deposit amount.     |
| `gasLimit`     | number          | No       | Optional gas limit. |

Uses API key bound `userAddress` — not a request body field.

## Record deposit tx

```
POST /api/v1/cash/deposits/tx
```

| Field    | Type   | Required | Description      |
| -------- | ------ | -------- | ---------------- |
| `txHash` | string | Yes      | Deposit tx hash. |

## Query deposits

```
GET /api/v1/cash/deposits?page=1&limit=10
GET /api/v1/cash/deposits/{operationId}
```

`operationId` is backfilled by the indexer after parsing chain events.

See [operation-status.md](/trading-api/cash-operations/operation-status) for response fields.


# Withdrawals

Withdrawals deduct `mUSD` (`mUsdBalance`) and return cash tokens to the user. They may complete instantly if the token withdrawal buffer has enough liquidity; otherwise they are queued for final cash settlement. See [buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism).

## Build withdrawal calldata

```
POST /api/v1/cash/withdrawals/calldata
```

| Field          | Type            | Required | Description                          |
| -------------- | --------------- | -------- | ------------------------------------ |
| `userAddress`  | string          | Yes      | User wallet.                         |
| `tokenAddress` | string          | Yes      | Cash token address.                  |
| `creditAmount` | string / number | Yes      | Credit to withdraw (human-readable). |

Returns `method: withdraw`, `value: "0"`.

## One Click withdrawal

```
POST /api/v1/cash/withdrawals/send
```

Same body fields as calldata (no `userAddress` in body — uses API key bound address). Optional `gasLimit`.

Requires One Click enabled — see [trading/one-click-delegated.md](/trading-api/trading/one-click-delegated).

## Record withdrawal tx

```
POST /api/v1/cash/withdrawals/tx
```

| Field    | Type   | Required | Description         |
| -------- | ------ | -------- | ------------------- |
| `txHash` | string | Yes      | Withdrawal tx hash. |

## Query withdrawals

```
GET /api/v1/cash/withdrawals?page=1&limit=10
GET /api/v1/cash/withdrawals/{operationId}
```

See [operation-status.md](/trading-api/cash-operations/operation-status) for response fields.


# Operation Status

Shared fields for deposit and withdrawal detail responses.

Cash operations can be instant or queued depending on Cashier buffers. See [buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism) for the buffer mechanism explanation.

## Response shape

`TradingCashOperationDetailRespDto`:

| Field                 | Type          | Description                |
| --------------------- | ------------- | -------------------------- |
| `mappingStatus`       | string / null | TX mapping status.         |
| `operationStatus`     | string / null | On-chain operation status. |
| `mapping`             | object        | Mapping record.            |
| `depositOperation`    | object / null | Deposit details.           |
| `withdrawalOperation` | object / null | Withdrawal details.        |

## depositOperation fields

| Field          | Type          | Description                                 |
| -------------- | ------------- | ------------------------------------------- |
| `operationId`  | string        | Deposit operation ID.                       |
| `userAddress`  | string        | User address.                               |
| `tokenAddress` | string        | Token address.                              |
| `status`       | string        | Operation status.                           |
| `isInstant`    | boolean       | Whether the operation used instant buffers. |
| `amount`       | number        | Token amount.                               |
| `creditAmount` | number        | `mUSD` amount.                              |
| `feeAmount`    | number        | Fee amount.                                 |
| `createTxHash` | string        | Creation tx.                                |
| `settleTxHash` | string / null | Settlement tx.                              |

## withdrawalOperation fields

| Field                | Type          | Description                                  |
| -------------------- | ------------- | -------------------------------------------- |
| `operationId`        | string        | Withdrawal operation ID.                     |
| `userAddress`        | string        | User address.                                |
| `tokenAddress`       | string        | Token address.                               |
| `status`             | string        | Operation status.                            |
| `isInstant`          | boolean       | Whether the operation used instant buffers.  |
| `creditAmount`       | number        | `mUSD` amount deducted.                      |
| `amount`             | number        | Token amount to pay out.                     |
| `feeAmount`          | number        | Fee amount.                                  |
| `failedPayoutAmount` | number / null | Token amount that failed to pay out, if any. |
| `createTxHash`       | string        | Creation tx.                                 |
| `settleTxHash`       | string / null | Settlement tx.                               |

`isInstant` indicates whether the operation used Cashier buffers. Queued operations can remain `processing` until final cash settlement completes.

## Status enums

| operationStatus | Description |
| --------------- | ----------- |
| `requested`     | Requested.  |
| `processing`    | Processing. |
| `settled`       | Settled.    |
| `closed`        | Closed.     |

`mappingStatus` reuses order mapping statuses — see [reference/enums.md](/trading-api/reference/enums).

## Query endpoints

| Operation | List                           | Detail                                       |
| --------- | ------------------------------ | -------------------------------------------- |
| Deposit   | `GET /api/v1/cash/deposits`    | `GET /api/v1/cash/deposits/{operationId}`    |
| Withdraw  | `GET /api/v1/cash/withdrawals` | `GET /api/v1/cash/withdrawals/{operationId}` |

After self-submit, poll by `operationId` once the indexer backfills it from `txHash`.


# Buffer Mechanism

The stock contracts use a dual-buffer design so small deposits and withdrawals can settle instantly without waiting for the full asynchronous cash settlement path. This page explains the mechanism from an API integration perspective.

## Why Buffers Exist

Deposits and withdrawals may need asynchronous cash settlement. Waiting for that full path on every operation would add latency to every API flow, so `Cashier` can use pre-funded liquidity to apply the result first and let final settlement catch up later.

The Cashier therefore keeps pre-funded buffers:

| Buffer             | Unit                             | Used for            | API-visible result                |
| ------------------ | -------------------------------- | ------------------- | --------------------------------- |
| `creditBuffer`     | `mUSD`, 18-decimal WAD           | Instant deposits    | `mUsdBalance` updates immediately |
| `withdrawalBuffer` | Per-token amount, token decimals | Instant withdrawals | Cash token transfers immediately  |

If the relevant buffer can cover the operation safely, the operation is instant. Otherwise it is queued and settled later.

## Deposit Path

```mermaid
sequenceDiagram
    participant U as User
    participant R as StockRouter
    participant C as Cashier

    U->>R: deposit token
    R->>C: deposit(user, token, amount)
    alt creditBuffer available and withdrawalBuffer has room
        C->>C: reduce creditBuffer
        C->>C: increase withdrawalBuffer
        C->>U: credit mUsdBalance instantly
    else buffer criteria not met
        C->>C: record pending deposit
        Note over C: final settlement completes later
        C->>U: credit mUsdBalance later
    end
```

On an instant deposit:

* Cash token moves in from the wallet.
* Cashier consumes `creditBuffer`.
* `mUsdBalance` updates immediately.
* The token amount, net of fee, replenishes that token's `withdrawalBuffer` up to capacity.

On a queued deposit:

* Cashier records a pending deposit operation.
* `mUSD` is not credited immediately.
* Cashier credits `mUSD` after final settlement.

## Withdrawal Path

```mermaid
sequenceDiagram
    participant U as User
    participant R as StockRouter
    participant C as Cashier

    U->>R: withdraw credit
    R->>C: withdraw(user, token, creditAmount)
    C->>C: deduct mUsdBalance
    alt withdrawalBuffer available
        C->>C: reduce withdrawalBuffer
        C->>C: replenish creditBuffer
        C->>U: transfer token instantly
    else buffer criteria not met
        C->>C: record pending withdrawal
        Note over C: final settlement completes later
        C->>U: transfer token later
    end
```

On an instant withdrawal:

* `mUsdBalance` is deducted first.
* Cashier pays the token from `withdrawalBuffer`.
* The deducted credit replenishes `creditBuffer` up to capacity.

On a queued withdrawal:

* `mUsdBalance` is deducted when the withdrawal is requested.
* Cashier records a pending withdrawal operation.
* Cashier transfers tokens after final settlement.

## Instant Eligibility

The contracts intentionally avoid draining buffers in one operation. An operation must be small enough relative to the current buffer and the buffer must have enough available capacity.

| Operation  | Instant requirements, simplified                                                                                                               |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Deposit    | Deposit credit is no more than `creditBuffer / instantThresholdDivisor`, `creditBuffer` can cover it, and the token withdrawal buffer has room |
| Withdrawal | Withdrawal token value is no more than `withdrawalBuffer / instantThresholdDivisor`, and `withdrawalBuffer` can cover it                       |

Anchored production uses `instantThresholdDivisor = 5`, so an instant operation is normally limited to at most 20% of the relevant current buffer. Operators can configure this value.

## Cross-Buffer Replenishment

The two buffers feed each other:

| Operation          | Consumes                 | Replenishes              |
| ------------------ | ------------------------ | ------------------------ |
| Instant deposit    | `creditBuffer`           | Token `withdrawalBuffer` |
| Instant withdrawal | Token `withdrawalBuffer` | `creditBuffer`           |

This is why deposits help future withdrawals and withdrawals help future deposits. Buffer manager operations can also rebalance or bootstrap buffers without changing the API flow.

## API-Visible Results

| Result                         | Likely meaning                                          | Integration guidance                      |
| ------------------------------ | ------------------------------------------------------- | ----------------------------------------- |
| `isInstant = true`             | Operation used available buffer                         | Treat operation as instantly applied      |
| `operationStatus = processing` | Operation is queued or settlement path is still running | Continue polling; do not treat as failure |
| `operationStatus = settled`    | Cashier has applied final credit or payout              | Refresh portfolio state                   |

For deposits, track when `mUsdBalance` updates. For withdrawals, track when tokens arrive in the wallet. The buffer mechanism only changes timing, not the eventual accounting path.

## Integration Guidance

* Do not assume every deposit or withdrawal is instant.
* Treat queued cash operations as normal product behavior.
* Poll the operation detail endpoint and refresh portfolio after final status.
* If a large operation is queued, retrying the same amount does not make it instant; it is constrained by current buffer size and capacity.

Related docs:

| Need                       | Doc                                                                                             |
| -------------------------- | ----------------------------------------------------------------------------------------------- |
| Live buffer and fee config | [../market/on-chain-config.md](/trading-api/market-data/on-chain-config) (`GET /api/v1/config`) |
| Deposit endpoints          | [deposits.md](/trading-api/cash-operations/deposits)                                            |
| Withdrawal endpoints       | [withdrawals.md](/trading-api/cash-operations/withdrawals)                                      |
| Cash status fields         | [operation-status.md](/trading-api/cash-operations/operation-status)                            |
| Status model               | [../reference/status-model.md](/trading-api/reference/status-model)                             |


# Overview

Docs for moving stock tokens between wallet balance and `Stock.stockBalance` (`exchangeBalance`).

| Need                             | Doc                                                                                   |
| -------------------------------- | ------------------------------------------------------------------------------------- |
| Deposit stock token into `Stock` | [deposits-and-withdrawals.md](/trading-api/stock-operations/deposits-and-withdrawals) |
| Withdraw stock token to wallet   | [deposits-and-withdrawals.md](/trading-api/stock-operations/deposits-and-withdrawals) |


# Deposits & Withdrawals

Stock endpoints move ERC-20 stock tokens between wallet balance and `Stock.stockBalance`. The API surfaces `Stock.stockBalance` as `exchangeBalance`.

Cash endpoints are separate. Use `/cash/**` only for cash-token flows into or out of `Cashier`.

## Build Stock Deposit Calldata

```
POST /api/v1/stock/deposits/calldata
```

| Field          | Type            | Required | Description                        |
| -------------- | --------------- | -------- | ---------------------------------- |
| `userAddress`  | string          | Yes      | User wallet.                       |
| `tokenAddress` | string          | Yes      | Stock token contract address.      |
| `tokenAmount`  | string / number | Yes      | Human-readable stock token amount. |

The user wallet must approve `StockRouter` for the stock token before the transaction can move wallet stock into `Stock`.

## One Click Stock Deposit

```
POST /api/v1/stock/deposits/send
```

| Field          | Type            | Required | Description                        |
| -------------- | --------------- | -------- | ---------------------------------- |
| `tokenAddress` | string          | Yes      | Stock token contract address.      |
| `tokenAmount`  | string / number | Yes      | Human-readable stock token amount. |
| `gasLimit`     | number          | No       | Optional gas limit.                |

Uses API key bound `userAddress`; do not include `userAddress` in the request body.

## Record Stock Deposit Tx

```
POST /api/v1/stock/deposits/tx
```

| Field    | Type   | Required | Description            |
| -------- | ------ | -------- | ---------------------- |
| `txHash` | string | Yes      | Stock deposit tx hash. |

## Query Stock Deposits

```
GET /api/v1/stock/deposits?page=1&limit=10
GET /api/v1/stock/deposits/{operationId}
```

## Build Stock Withdrawal Calldata

```
POST /api/v1/stock/withdrawals/calldata
```

| Field          | Type            | Required | Description                        |
| -------------- | --------------- | -------- | ---------------------------------- |
| `userAddress`  | string          | Yes      | User wallet.                       |
| `tokenAddress` | string          | Yes      | Stock token contract address.      |
| `tokenAmount`  | string / number | Yes      | Human-readable stock token amount. |

Withdrawals deduct `Stock.stockBalance` and transfer ERC-20 stock tokens to the wallet.

## One Click Stock Withdrawal

```
POST /api/v1/stock/withdrawals/send
```

| Field          | Type            | Required | Description                        |
| -------------- | --------------- | -------- | ---------------------------------- |
| `tokenAddress` | string          | Yes      | Stock token contract address.      |
| `tokenAmount`  | string / number | Yes      | Human-readable stock token amount. |
| `gasLimit`     | number          | No       | Optional gas limit.                |

Uses API key bound `userAddress`; do not include `userAddress` in the request body.

## Record Stock Withdrawal Tx

```
POST /api/v1/stock/withdrawals/tx
```

| Field    | Type   | Required | Description               |
| -------- | ------ | -------- | ------------------------- |
| `txHash` | string | Yes      | Stock withdrawal tx hash. |

## Query Stock Withdrawals

```
GET /api/v1/stock/withdrawals?page=1&limit=10
GET /api/v1/stock/withdrawals/{operationId}
```

`operationId` is an API/indexer identifier for looking up the recorded stock operation. The `Stock` contract emits deposit and withdrawal events, but those events do not include a contract-native `operationId`.


# Overview

End-to-end guides for RWA API integrations.

| Need                       | Doc                                                                     |
| -------------------------- | ----------------------------------------------------------------------- |
| First successful trade     | [quickstart-first-trade.md](/trading-api/guides/quickstart-first-trade) |
| Self-submit flow           | [self-submit-on-chain.md](/trading-api/guides/self-submit-on-chain)     |
| One Click flow             | [one-click-flow.md](/trading-api/guides/one-click-flow)                 |
| TypeScript / viem examples | [demo-code.md](/trading-api/guides/demo-code)                           |

Start with the quickstart, then use self-submit or One Click depending on who broadcasts router transactions.


# Quickstart: First API Trade

This guide walks through the smallest API flow for a partner integration:

1. Discover a tradable stock.
2. Confirm `mUSD`.
3. Deposit if needed.
4. Place a market buy.
5. Record and track the transaction.
6. Confirm the portfolio changed after settlement.

Use this as the smoke test before adding limit orders, withdrawals, or One Click.

## Flow

```mermaid
flowchart TB
    A[Configure API key] --> B[GET symbols]
    B --> C[Pick tradable symbol]
    C --> D[GET user balance]
    D --> E{Enough mUSD}
    E -->|no| F[Approve cash token]
    F --> G[Deposit cash]
    G --> H[Wait for mUSD]
    E -->|yes| I[Build market buy calldata]
    H --> I
    I --> J[Submit router transaction]
    J --> K[Record txHash]
    K --> L[Wait for orderId]
    L --> M[Poll order detail]
    M --> N[Confirm portfolio]
```

## 1. Configure Request Context

Every request must include:

| Header           | Example                             |
| ---------------- | ----------------------------------- |
| `x-api-key`      | Partner API key                     |
| `x-api-ts`       | Current Unix milliseconds           |
| `x-api-nonce`    | UUID                                |
| `x-api-sign`     | HMAC-SHA256 authentication value    |
| `x-api-chain-id` | `8453`, `143`, `1`, or target chain |
| `x-api-p`        | `Anchored` for the Anchored API     |

Use the exact `/api/v1/...` path in the HMAC payload. Do not include the domain or `/rwa/trading`.

## 2. Discover a Tradable Stock

```
GET /api/v1/symbols
```

Pick an item where `tradable` is `true`. Relevant response fields:

| Field             | Use                               |
| ----------------- | --------------------------------- |
| `symbol`          | Symbol and quote lookup           |
| `contractAddress` | `stockAddress` for order requests |
| `price`           | Quote context                     |

Optional quote refresh:

```
GET /api/v1/prices/{symbol}
```

## 3. Check Portfolio

```
GET /api/v1/users/{userId}/balance
```

For a plain market buy, check `mUsdBalance`, the API field for `mUSD`. Wallet USDC is not buying power until it is deposited into `mUSD`. If the cash token is approved and instant deposit is available, `/api/v1/orders/with-deposit/calldata` can deposit and place the buy in one transaction.

## 4. Deposit Cash If Needed

First check allowance:

```
GET /api/v1/users/{userId}/balance?spenderAddress={spender}
```

If allowance is too low, have the user approve the spender from [cash/deposits.md](/trading-api/cash-operations/deposits).

Then build deposit calldata:

```
POST /api/v1/cash/deposits/calldata
```

Example body:

```json
{
  "userAddress": "0x1111111111111111111111111111111111111111",
  "tokenAddress": "0x2222222222222222222222222222222222222222",
  "tokenAmount": "100"
}
```

Submit the returned `toAddress`, `value`, and `callData` on-chain. Then record:

```
POST /api/v1/cash/deposits/tx
```

Poll deposit detail until `operationStatus` is `settled` or `mUsdBalance` is updated.

## 5. Place a Market Buy

Build order calldata:

```
POST /api/v1/orders/calldata
```

Example body:

```json
{
  "stockAddress": "0x3333333333333333333333333333333333333333",
  "side": "Buy",
  "type": "Market",
  "notional": "10",
  "deadline": 1893456000
}
```

Submit the returned `StockRouter` transaction with your wallet client.

## 6. Record and Track the Order

Record the self-submitted tx:

```
POST /api/v1/orders/tx
```

Example:

```json
{
  "txHash": "0xabc..."
}
```

Then track:

```
GET /api/v1/orders/tx/{txHash}
GET /api/v1/orders/{orderId}
```

The transaction can be mined before execution and settlement are final. Treat the order as final only after it moves into history and portfolio balances reflect the settlement.

## 7. Confirm Portfolio

After settlement:

```
GET /api/v1/users/{userId}/balance
GET /api/v1/users/{userId}/positions
```

Expected result:

* `mUsdBalance` decreases by filled notional plus fees, with unspent `mUSD` refunded.
* The bought stock appears as `exchangeBalance`.
* Order detail shows settlement fields such as `settlePrice`, `settlePay`, and `settleReceive`.

## Next Steps

| Need                | Doc                                                                       |
| ------------------- | ------------------------------------------------------------------------- |
| viem implementation | [demo-code.md](/trading-api/guides/demo-code)                             |
| Debug failures      | [../reference/troubleshooting.md](/trading-api/reference/troubleshooting) |
| Understand statuses | [../reference/status-model.md](/trading-api/reference/status-model)       |
| Add One Click       | [one-click-flow.md](/trading-api/guides/one-click-flow)                   |


# Self-Submit On-Chain

For integrators who sign and broadcast transactions with their own wallet or custodian.

## Workflow

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant Chain
    participant Indexer

    Client->>API: POST /orders/calldata
    API-->>Client: calldata + toAddress
    Client->>Chain: Submit transaction
    Chain-->>Client: txHash
    Client->>API: POST /orders/tx { txHash }
    API-->>Client: Mapping record
    Indexer->>API: Parse on-chain events, backfill orderId
    Client->>API: GET /orders/{orderId}
    API-->>Client: Order status
```

## Steps

1. Call `/calldata` for the operation:
   * Orders: `POST /api/v1/orders/calldata`
   * Deposits: `POST /api/v1/cash/deposits/calldata`
   * Withdrawals: `POST /api/v1/cash/withdrawals/calldata`
2. Submit `toAddress`, `value`, and `callData` on-chain.
3. Call the matching `/tx` endpoint with `txHash`.
4. Indexer backfills `orderId` or `operationId`.
5. Poll status endpoints until settled.

> **Use a reliable RPC node.** `estimateGas`, `eth_call`, and `waitForTransactionReceipt` hit your RPC provider, not the Anchored API. Free/public endpoints (including viem's default `http()` transport and free-tier providers) may rate-limit or reject `eth_call` and gas estimation, failing *before* the API is involved. Pass your own node URL to `http("<url>")`.
>
> **Add a gas buffer.** Default `estimateGas` can under-estimate router calls on some chains (e.g. Monad) and the tx reverts out-of-gas. Multiply the estimate (e.g. `× 1.5–2`) before submitting.

## Record tx endpoints

| Operation   | Endpoint                           |
| ----------- | ---------------------------------- |
| Place order | `POST /api/v1/orders/tx`           |
| Deposit     | `POST /api/v1/cash/deposits/tx`    |
| Withdraw    | `POST /api/v1/cash/withdrawals/tx` |

## Status queries

| Operation | Endpoints                                                        |
| --------- | ---------------------------------------------------------------- |
| Order     | `GET /api/v1/orders/tx/{txHash}`, `GET /api/v1/orders/{orderId}` |
| Deposit   | `GET /api/v1/cash/deposits/{operationId}`                        |
| Withdraw  | `GET /api/v1/cash/withdrawals/{operationId}`                     |

> Same `txHash` from the same API key is idempotent. A `txHash` already recorded by another API key returns an error.

## Deposit prerequisite

Complete ERC-20 `approve` before deposit calldata execution. See [cash/deposits.md](/trading-api/cash-operations/deposits) and [demo-code.md](/trading-api/guides/demo-code).


# One Click Flow

For API keys with a bound user wallet address. The server submits transactions after the user delegates once.

## Authorization

```mermaid
sequenceDiagram
    participant User
    participant Client
    participant API
    participant Chain

    Client->>API: GET /1ct/status
    API-->>Client: { status: "disabled" }
    Client->>API: POST /1ct/prepare { deadline }
    API-->>Client: signPayload (EIP-712)
    Client->>User: Request signature
    User->>Client: signature (65 bytes)
    Client->>API: POST /1ct/enable { signature, deadline }
    API->>Chain: delegateBySig
    API-->>Client: { status: "enable" }
```

## Steps

1. `GET /api/v1/1ct/status` — check delegation.
2. If not enabled: `POST /api/v1/1ct/prepare` → user signs EIP-712 → `POST /api/v1/1ct/enable`.
3. Call `/send` endpoints for orders and cash.

Details: [trading/one-click-delegated.md](/trading-api/trading/one-click-delegated). viem example: [demo-code.md](/trading-api/guides/demo-code).

## Send endpoints

| Operation    | Endpoint                               |
| ------------ | -------------------------------------- |
| Place order  | `POST /api/v1/orders/send`             |
| Cancel order | `DELETE /api/v1/orders/{orderId}/send` |
| Deposit      | `POST /api/v1/cash/deposits/send`      |
| Withdraw     | `POST /api/v1/cash/withdrawals/send`   |

## Deposit prerequisite

User wallet must `approve` the cash token spender before `/cash/deposits/send`.

Approval owner is the API key bound `userAddress`. See [cash/deposits.md](/trading-api/cash-operations/deposits) for spender addresses.


# Demo Code

TypeScript examples for RWA API integration. HMAC authentication uses Node `crypto`; on-chain actions use [viem](https://viem.sh).

```bash
npm install viem
```

Set environment variables:

```bash
export TRADING_API_KEY="your-api-key"
export TRADING_API_SECRET="your-api-secret"
export TRADING_USER_PRIVATE_KEY="0x..."   # self-submit / One Click user wallet
```

## API client with HMAC

```ts
import crypto from "node:crypto";

const BASE_URL = "https://rwa-api.anchored.finance/rwa/trading";

type HttpMethod = "GET" | "POST" | "DELETE";

interface TradingApiConfig {
    apiKey: string;
    apiSecret: string;
    chainId: number;
    productType: "Anchored";
}

function canonicalUri(path: string, query: Record<string, string | string[] | undefined> = {}): string {
    const pairs: string[] = [];
    for (const key of Object.keys(query).sort()) {
        const value = query[key];
        if (value === undefined || value === null) continue;
        if (Array.isArray(value)) {
            for (const item of value) pairs.push(`${key}=${item}`);
        } else {
            pairs.push(`${key}=${value}`);
        }
    }
    return pairs.length === 0 ? path : `${path}?${pairs.join("&")}`;
}

function signTradingApi(
    apiSecret: string,
    method: HttpMethod,
    path: string,
    query: Record<string, string | string[] | undefined>,
    timestamp: number,
    nonce: string,
    rawBody: string,
): string {
    const uri = canonicalUri(path, query);
    const payload = [method, uri, String(timestamp), nonce, rawBody].join("\n");
    return crypto.createHmac("sha256", apiSecret).update(payload, "utf8").digest("hex");
}

async function tradingApiRequest<T>(
    config: TradingApiConfig,
    method: HttpMethod,
    path: string,
    options: {
        query?: Record<string, string | string[] | undefined>;
        body?: unknown;
    } = {},
): Promise<T> {
    const query = options.query ?? {};
    const rawBody = options.body === undefined ? "" : JSON.stringify(options.body);
    const timestamp = Date.now();
    const nonce = crypto.randomUUID();
    const signature = signTradingApi(config.apiSecret, method, path, query, timestamp, nonce, rawBody);

    const url = new URL(`${BASE_URL}${canonicalUri(path, query)}`);
    const response = await fetch(url, {
        method,
        headers: {
            "content-type": "application/json",
            "x-api-key": config.apiKey,
            "x-api-ts": String(timestamp),
            "x-api-nonce": nonce,
            "x-api-sign": signature,
            "x-api-chain-id": String(config.chainId),
            "x-api-p": config.productType,
        },
        body: method === "GET" || method === "DELETE" ? undefined : rawBody,
    });

    const json = await response.json() as { code?: number; errMsg?: string; data?: T };
    if (json.code !== 200) {
        throw new Error(json.errMsg || `API error ${json.code}`);
    }
    return json.data as T;
}
```

## Self-submit market buy (viem)

Build calldata from the API, broadcast with viem, then record the tx hash.

```ts
import { createPublicClient, createWalletClient, http, type Address, type Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";

interface OrderCalldata {
    chainId: number;
    productType: string;
    toAddress: Address;
    value: string;
    callData: Hex;
    method: string;
}

const config: TradingApiConfig = {
    apiKey: process.env.TRADING_API_KEY!,
    apiSecret: process.env.TRADING_API_SECRET!,
    chainId: 8453,
    productType: "Anchored",
};

const account = privateKeyToAccount(process.env.TRADING_USER_PRIVATE_KEY as Hex);
const walletClient = createWalletClient({
    account,
    chain: base,
    transport: http(),
});
const publicClient = createPublicClient({ chain: base, transport: http() });

// Router calls under-estimate gas on some chains (e.g. Monad): the default
// estimate can leave the tx short and it reverts out-of-gas. Add a buffer.
async function submitTx(to: Address, callData: Hex, value: string): Promise<Hex> {
    const gas = (await publicClient.estimateGas({
        account: account.address,
        to,
        data: callData,
        value: BigInt(value),
    })) * 2n;
    return walletClient.sendTransaction({ to, data: callData, value: BigInt(value), gas });
}

async function placeMarketBuySelfSubmit(stockAddress: Address, notional: string): Promise<Hex> {
    const calldata = await tradingApiRequest<OrderCalldata>(config, "POST", "/api/v1/orders/calldata", {
        body: {
            stockAddress,
            side: "Buy",
            type: "Market",
            notional,
            deadline: Math.floor(Date.now() / 1000) + 3600,
        },
    });

    const txHash = await submitTx(calldata.toAddress, calldata.callData, calldata.value);

    await tradingApiRequest(config, "POST", "/api/v1/orders/tx", {
        body: { txHash },
    });

    return txHash;
}
```

## Deposit with ERC-20 approve (viem)

Approve the spender, then self-submit deposit calldata.

```ts
import { erc20Abi, maxUint256, type Address, type Hex } from "viem";

// Reuses the module-level `walletClient`, `publicClient`, `account`, `config`,
// and `submitTx` defined above.
const SPENDER: Address = "0x4f090d817fd83753988a7b0c1d76f170f8461be8"; // Anchored mainnet StockRouter

interface CashCalldata {
    chainId: number;
    productType: string;
    toAddress: Address;
    value: string;
    callData: Hex;
    method: string;
}

async function depositSelfSubmit(tokenAddress: Address, tokenAmount: string): Promise<Hex> {
    const approveHash = await walletClient.writeContract({
        address: tokenAddress,
        abi: erc20Abi,
        functionName: "approve",
        args: [SPENDER, maxUint256],
    });
    await publicClient.waitForTransactionReceipt({ hash: approveHash });

    const calldata = await tradingApiRequest<CashCalldata>(config, "POST", "/api/v1/cash/deposits/calldata", {
        body: {
            userAddress: account.address,
            tokenAddress,
            tokenAmount,
        },
    });

    const txHash = await submitTx(calldata.toAddress, calldata.callData, calldata.value);

    await tradingApiRequest(config, "POST", "/api/v1/cash/deposits/tx", {
        body: { txHash },
    });

    return txHash;
}
```

Spender addresses: [cash/deposits.md](/trading-api/cash-operations/deposits).

## Order with deposit (self-submit)

Use `/orders/with-deposit/calldata` when the same transaction should deposit an approved token and place an order. For buy orders, the cash deposit must be eligible for instant deposit. The token must be approved before submitting the returned calldata.

```ts
async function placeMarketBuyWithDepositSelfSubmit(
    cashTokenAddress: Address,
    stockAddress: Address,
    depositAmount: string,
    notional: string,
): Promise<Hex> {
    const calldata = await tradingApiRequest<OrderCalldata>(config, "POST", "/api/v1/orders/with-deposit/calldata", {
        body: {
            stockAddress,
            depositTokenAddress: cashTokenAddress,
            depositAmount,
            side: "Buy",
            type: "Market",
            notional,
            deadline: Math.floor(Date.now() / 1000) + 3600,
        },
    });

    const txHash = await submitTx(calldata.toAddress, calldata.callData, calldata.value);

    await tradingApiRequest(config, "POST", "/api/v1/orders/tx", {
        body: { txHash },
    });

    return txHash;
}
```

## Stock deposit and withdrawal (self-submit)

Stock endpoints move ERC-20 stock tokens between wallet balance and `exchangeBalance`. Approve `StockRouter` for the stock token before calling stock deposit calldata.

```ts
async function depositStockSelfSubmit(stockTokenAddress: Address, tokenAmount: string): Promise<Hex> {
    const calldata = await tradingApiRequest<OrderCalldata>(config, "POST", "/api/v1/stock/deposits/calldata", {
        body: {
            userAddress: account.address,
            tokenAddress: stockTokenAddress,
            tokenAmount,
        },
    });

    const txHash = await submitTx(calldata.toAddress, calldata.callData, calldata.value);

    await tradingApiRequest(config, "POST", "/api/v1/stock/deposits/tx", {
        body: { txHash },
    });

    return txHash;
}

async function withdrawStockSelfSubmit(stockTokenAddress: Address, tokenAmount: string): Promise<Hex> {
    const calldata = await tradingApiRequest<OrderCalldata>(config, "POST", "/api/v1/stock/withdrawals/calldata", {
        body: {
            userAddress: account.address,
            tokenAddress: stockTokenAddress,
            tokenAmount,
        },
    });

    const txHash = await submitTx(calldata.toAddress, calldata.callData, calldata.value);

    await tradingApiRequest(config, "POST", "/api/v1/stock/withdrawals/tx", {
        body: { txHash },
    });

    return txHash;
}
```

## One Click enable (viem signTypedData)

User signs the EIP-712 payload from `/1ct/prepare`, then submits to `/1ct/enable`.

```ts
interface OneClickPrepare {
    delegatee: Address;
    signPayload: {
        domain: {
            name: string;
            version: string;
            chainId: number;
            verifyingContract: Address;
        };
        types: {
            // /1ct/prepare also returns EIP712Domain here; it must be stripped
            // before passing to viem signTypedData (viem derives it from `domain`).
            EIP712Domain?: Array<{ name: string; type: string }>;
            Delegate: Array<{ name: string; type: string }>;
        };
        primaryType: "Delegate";
        message: {
            user: Address;
            delegatee: Address;
            nonce: bigint | number;
            deadline: bigint | number;
        };
    };
    nonce: number;
    deadline: number;
}

async function enableOneClick(): Promise<void> {
    const deadline = Math.floor(Date.now() / 1000) + 3600;
    const prepared = await tradingApiRequest<OneClickPrepare>(config, "POST", "/api/v1/1ct/prepare", {
        body: { deadline },
    });

    const { signPayload } = prepared;
    if (account.address.toLowerCase() !== signPayload.message.user.toLowerCase()) {
        throw new Error("signer must match signPayload.message.user");
    }

    // viem derives EIP712Domain from `domain`; leaving it in `types` throws, so strip it.
    const types = { ...signPayload.types };
    delete types.EIP712Domain;
    const signature = await walletClient.signTypedData({
        domain: {
            ...signPayload.domain,
            chainId: BigInt(signPayload.domain.chainId),
        },
        types,
        primaryType: signPayload.primaryType,
        message: {
            ...signPayload.message,
            nonce: BigInt(signPayload.message.nonce),
            deadline: BigInt(signPayload.message.deadline),
        },
    });

    await tradingApiRequest(config, "POST", "/api/v1/1ct/enable", {
        body: { signature, deadline: prepared.deadline },
    });
}
```

After enable, use `/send` endpoints — see [one-click-flow.md](/trading-api/guides/one-click-flow).

## One Click order (via `/send`)

Once One Click is enabled, place orders with `/orders/send`. The API builds the calldata and broadcasts it through `OneClickRouter`, paying gas on the user's behalf — no per-order wallet signature or self-broadcast. The body is the same as `/orders/calldata`, plus an optional `gasLimit` (set a buffer; router calls can under-estimate gas on some chains). The response is the order-tx mapping, not calldata: poll it (or `/orders/tx/{txHash}`) until `orderId` is populated.

```ts
interface OneClickOrderTx {
    id: string;
    chainId: number;
    productType: string;
    operationType: string;      // "trade"
    orderId: string | null;     // null until indexed, then the on-chain order id
    txHash: string;
    status: string;             // "pending" -> "new" -> ...
    createAt: string;
    updateAt: string;
}

async function placeLimitBuyOneClick(
    stockAddress: Address,
    quantity: string,
    price: string,
): Promise<OneClickOrderTx> {
    return tradingApiRequest<OneClickOrderTx>(config, "POST", "/api/v1/orders/send", {
        body: {
            stockAddress,
            side: "Buy",
            type: "Limit",
            quantity,
            price,
            timeInForce: "DAY", // production limit orders only accept DAY
            deadline: Math.floor(Date.now() / 1000) + 3600,
            gasLimit: 800000,   // gas buffer; API broadcasts via OneClickRouter
        },
    });
}
```

Cancel an open One Click order the same way — `DELETE /api/v1/orders/{orderId}/send` (query `deadline` required, `gasLimit` optional) — which also broadcasts through the router.

## Query portfolio

```ts
interface UserBalance {
    chainId: number;
    productType: string;
    address: Address;
    mUsdBalance: string;
    tokenBalances: Array<{
        symbol: string;
        stockSymbol?: string;
        isStock: boolean;
        walletBalance: string;
        exchangeBalance: string;
        price?: number;
    }>;
}

async function getPortfolio(userId: Address): Promise<UserBalance> {
    return tradingApiRequest<UserBalance>(
        config,
        "GET",
        `/api/v1/users/${userId.toLowerCase()}/balance`,
    );
}
```

## Query corporate actions

```ts
interface BrokerCorporateAction {
    symbol: string;
    type: "reverse_splits" | "forward_splits" | "unit_splits" | "stock_dividends" | "cash_dividends";
    time: string;
    exDate: string;
    recordDate: string;
    payableDate: string;
    processDate: string;
    info: Record<string, unknown>;
}

async function getCorporateActions(symbol: string): Promise<BrokerCorporateAction[]> {
    return tradingApiRequest<BrokerCorporateAction[]>(config, "GET", "/api/v1/corporate-action", {
        query: { symbol, types: ["cash_dividends"] },
    });
}
```

See also [authenticate/examples.md](/trading-api/authentication/examples) for Node.js-only HMAC snippets.


# Overview

Reference docs for production RWA API integrations.

| Need                                | Doc                                                                                                                                                   |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| All endpoints                       | [endpoint-index.md](/trading-api/reference/endpoint-index)                                                                                            |
| Enums and constraints               | [enums.md](/trading-api/reference/enums)                                                                                                              |
| Status and UI state model           | [status-model.md](/trading-api/reference/status-model)                                                                                                |
| Troubleshooting                     | [troubleshooting.md](/trading-api/reference/troubleshooting)                                                                                          |
| API endpoint to contract effect     | [api-contract-map.md](/trading-api/reference/api-contract-map)                                                                                        |
| Environments, chains, product types | [environments-and-chains.md](/trading-api/reference/environments-and-chains)                                                                          |
| Sample responses                    | [sample-responses.md](/trading-api/reference/sample-responses)                                                                                        |
| Production test checklist           | [integration-test-checklist.md](/trading-api/reference/integration-test-checklist)                                                                    |
| Live OpenAPI snapshot               | [openapi.snapshot.json](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/reference/openapi.snapshot.json) |


# Endpoint Index

**46 endpoints** for RWA trading integrators. Permission: `READ_ONLY` or `WRITABLE` per API key scope.

Base path: `/api/v1`. Full URL prefix: `https://rwa-api.anchored.finance/rwa/trading`.

## Market data (6)

| Method | Path                                | Permission | Description            |
| ------ | ----------------------------------- | ---------- | ---------------------- |
| `GET`  | `/api/v1/config`                    | READ\_ONLY | On-chain market config |
| `GET`  | `/api/v1/symbols`                   | READ\_ONLY | Tradable symbols       |
| `GET`  | `/api/v1/prices/{symbol}`           | READ\_ONLY | Real-time quote        |
| `GET`  | `/api/v1/prices/{symbol}/history`   | READ\_ONLY | K-line history         |
| `GET`  | `/api/v1/underlying/{symbol}/price` | READ\_ONLY | Underlying quote       |
| `GET`  | `/api/v1/corporate-action`          | READ\_ONLY | Corporate actions      |

## Portfolio (3)

| Method | Path                               | Permission | Description |
| ------ | ---------------------------------- | ---------- | ----------- |
| `GET`  | `/api/v1/users/{userId}`           | READ\_ONLY | User info   |
| `GET`  | `/api/v1/users/{userId}/balance`   | READ\_ONLY | Balances    |
| `GET`  | `/api/v1/users/{userId}/positions` | READ\_ONLY | Positions   |

## Orders (10)

| Method   | Path                                   | Permission | Description                       |
| -------- | -------------------------------------- | ---------- | --------------------------------- |
| `GET`    | `/api/v1/orders`                       | READ\_ONLY | Order list                        |
| `POST`   | `/api/v1/orders/calldata`              | WRITABLE   | Build order calldata              |
| `POST`   | `/api/v1/orders/send`                  | WRITABLE   | One Click order                   |
| `POST`   | `/api/v1/orders/with-deposit/calldata` | WRITABLE   | Build order-with-deposit calldata |
| `POST`   | `/api/v1/orders/with-deposit/send`     | WRITABLE   | One Click order with deposit      |
| `POST`   | `/api/v1/orders/tx`                    | WRITABLE   | Record order tx                   |
| `GET`    | `/api/v1/orders/tx/{txHash}`           | READ\_ONLY | Order by tx                       |
| `GET`    | `/api/v1/orders/{orderId}`             | READ\_ONLY | Order detail                      |
| `DELETE` | `/api/v1/orders/{orderId}/calldata`    | WRITABLE   | Cancel calldata                   |
| `DELETE` | `/api/v1/orders/{orderId}/send`        | WRITABLE   | One Click cancel                  |

## Deferred Sell (3)

| Method | Path                                   | Permission | Description                                 |
| ------ | -------------------------------------- | ---------- | ------------------------------------------- |
| `POST` | `/api/v1/deferred-sell/repay/calldata` | WRITABLE   | Build repay debt calldata                   |
| `POST` | `/api/v1/deferred-sell/repay/send`     | WRITABLE   | One Click repay debt                        |
| `GET`  | `/api/v1/deferred-sell/debts`          | READ\_ONLY | Outstanding debts (optional `stockAddress`) |

Deferred sells are **placed** through the [Orders](#orders-10) endpoints (`/api/v1/orders/calldata` and `/api/v1/orders/send`) with `deferred: true` + `side: Sell`, and queried/cancelled there too (responses carry a `deferred: true` flag). Only debt repayment and the debt query are deferred-specific.

## Cash (10)

| Method | Path                                     | Permission | Description        |
| ------ | ---------------------------------------- | ---------- | ------------------ |
| `POST` | `/api/v1/cash/deposits/calldata`         | WRITABLE   | Deposit calldata   |
| `POST` | `/api/v1/cash/deposits/send`             | WRITABLE   | One Click deposit  |
| `POST` | `/api/v1/cash/deposits/tx`               | WRITABLE   | Record deposit tx  |
| `GET`  | `/api/v1/cash/deposits`                  | READ\_ONLY | Deposit list       |
| `GET`  | `/api/v1/cash/deposits/{operationId}`    | READ\_ONLY | Deposit detail     |
| `POST` | `/api/v1/cash/withdrawals/calldata`      | WRITABLE   | Withdraw calldata  |
| `POST` | `/api/v1/cash/withdrawals/send`          | WRITABLE   | One Click withdraw |
| `POST` | `/api/v1/cash/withdrawals/tx`            | WRITABLE   | Record withdraw tx |
| `GET`  | `/api/v1/cash/withdrawals`               | READ\_ONLY | Withdraw list      |
| `GET`  | `/api/v1/cash/withdrawals/{operationId}` | READ\_ONLY | Withdraw detail    |

## Stock (10)

| Method | Path                                      | Permission | Description                |
| ------ | ----------------------------------------- | ---------- | -------------------------- |
| `POST` | `/api/v1/stock/deposits/calldata`         | WRITABLE   | Stock deposit calldata     |
| `POST` | `/api/v1/stock/deposits/send`             | WRITABLE   | One Click stock deposit    |
| `POST` | `/api/v1/stock/deposits/tx`               | WRITABLE   | Record stock deposit tx    |
| `GET`  | `/api/v1/stock/deposits`                  | READ\_ONLY | Stock deposit list         |
| `GET`  | `/api/v1/stock/deposits/{operationId}`    | READ\_ONLY | Stock deposit detail       |
| `POST` | `/api/v1/stock/withdrawals/calldata`      | WRITABLE   | Stock withdrawal calldata  |
| `POST` | `/api/v1/stock/withdrawals/send`          | WRITABLE   | One Click stock withdrawal |
| `POST` | `/api/v1/stock/withdrawals/tx`            | WRITABLE   | Record stock withdrawal tx |
| `GET`  | `/api/v1/stock/withdrawals`               | READ\_ONLY | Stock withdrawal list      |
| `GET`  | `/api/v1/stock/withdrawals/{operationId}` | READ\_ONLY | Stock withdrawal detail    |

## One Click (4)

| Method | Path                  | Permission | Description        |
| ------ | --------------------- | ---------- | ------------------ |
| `GET`  | `/api/v1/1ct/status`  | READ\_ONLY | Delegation status  |
| `POST` | `/api/v1/1ct/prepare` | WRITABLE   | EIP-712 payload    |
| `POST` | `/api/v1/1ct/enable`  | WRITABLE   | Enable delegation  |
| `POST` | `/api/v1/1ct/disable` | WRITABLE   | Disable delegation |

## Doc map

| Module        | Doc                                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Market        | [market/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/market/README.md)   |
| Portfolio     | [portfolio/overview.md](/trading-api/portfolio/overview)                                                                   |
| Orders        | [trading/](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/trading/README.md) |
| Deferred Sell | [trading/deferred-sell.md](/trading-api/trading/deferred-sell)                                                             |
| Cash          | [cash/](/trading-api/cash-operations/cash)                                                                                 |
| Stock         | [stock/](/trading-api/stock-operations/stock)                                                                              |
| One Click     | [trading/one-click-delegated.md](/trading-api/trading/one-click-delegated)                                                 |

## Related reference

| Need                          | Doc                                                                                |
| ----------------------------- | ---------------------------------------------------------------------------------- |
| API to contract effects       | [api-contract-map.md](/trading-api/reference/api-contract-map)                     |
| Environment and chain context | [environments-and-chains.md](/trading-api/reference/environments-and-chains)       |
| Status model                  | [status-model.md](/trading-api/reference/status-model)                             |
| Troubleshooting               | [troubleshooting.md](/trading-api/reference/troubleshooting)                       |
| Sample responses              | [sample-responses.md](/trading-api/reference/sample-responses)                     |
| Integration tests             | [integration-test-checklist.md](/trading-api/reference/integration-test-checklist) |

OpenAPI snapshot: [openapi.snapshot.json](https://github.com/AnchoredLabs/anchored-knowledge/tree/api-doc/anchored/02-products/rwa/api/reference/openapi.snapshot.json) (refreshed 2026-07-03 from live; server `https://rwa-api.anchored.finance/rwa/trading`)


# API ↔ Contract Map

This page maps partner API endpoints to the contract-level effect they prepare, submit, or query. Use it when debugging or explaining why an API call changes `mUSD`, `Stock.stockBalance`, or order state.

## Overview

```mermaid
flowchart TB
    API[Trading API] --> Router[StockRouter]
    Router --> Cashier[Cashier]
    Router --> Stock[Stock]
    Stock --> Cashier
```

## Market and Portfolio

| Endpoint                                | Contract relationship                        | Effect                                                                         |
| --------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------ |
| `GET /api/v1/config`                    | Reads on-chain Cashier/Exchange config cache | Returns fee rates, buffer state, and per-token cashier limits; no state change |
| `GET /api/v1/symbols`                   | Reads backend/token registry                 | Lists tradable stock tokens and contract addresses                             |
| `GET /api/v1/prices/{symbol}`           | Off-chain quote plus on-chain token context  | Quote display; no state change                                                 |
| `GET /api/v1/prices/{symbol}/history`   | Market data                                  | Historical display; no state change                                            |
| `GET /api/v1/underlying/{symbol}/price` | Market data                                  | Underlying quote; no state change                                              |
| `GET /api/v1/corporate-action`          | Corporate action data                        | Split/dividend data; no state change                                           |
| `GET /api/v1/users/{userId}/balance`    | Cashier + token balances + allowance         | Portfolio, buy power, deposit readiness                                        |
| `GET /api/v1/users/{userId}/positions`  | Indexed Stock state                          | Stock positions                                                                |

## Orders

| Endpoint                                    | Contract relationship                                                                                                        | Effect                                                                                                                                                      |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /api/v1/orders/calldata`              | Encodes `StockRouter.placeMarketOrder`/`placeLimitOrder` — or `deferredMarketSell`/`deferredLimitSell` when `deferred: true` | Returns tx data; no state change until submitted. `deferred: true` (sell only) is gated on the deferred-sell whitelist. See [Deferred Sell](#deferred-sell) |
| `POST /api/v1/orders/send`                  | OneClickRouter forwards to StockRouter                                                                                       | Places order (incl. **deferred sell** when `deferred: true`) and auto-records tx                                                                            |
| `POST /api/v1/orders/with-deposit/calldata` | Encodes `StockRouter.depositAndMarketBuy`, `depositAndLimitBuy`, `depositStockAndMarketSell`, or `depositStockAndLimitSell`  | Returns tx data for combined deposit + order                                                                                                                |
| `POST /api/v1/orders/with-deposit/send`     | OneClickRouter forwards combined deposit + order                                                                             | Submits combined flow and auto-records tx                                                                                                                   |
| `POST /api/v1/orders/tx`                    | API/indexer mapping                                                                                                          | Links self-submitted tx to API key                                                                                                                          |
| `GET /api/v1/orders`                        | API order mapping / indexed state                                                                                            | Lists mapped orders                                                                                                                                         |
| `GET /api/v1/orders/tx/{txHash}`            | API tx mapping                                                                                                               | Finds order by tx                                                                                                                                           |
| `GET /api/v1/orders/{orderId}`              | Indexed Stock state                                                                                                          | Shows open or historical order                                                                                                                              |
| `DELETE /api/v1/orders/{orderId}/calldata`  | Encodes `StockRouter.cancelLimitOrder`                                                                                       | Returns cancel tx data                                                                                                                                      |
| `DELETE /api/v1/orders/{orderId}/send`      | OneClickRouter forwards cancel                                                                                               | Cancels via delegated execution                                                                                                                             |

## Deferred Sell

A deferred sell is **placed / listed / detailed / cancelled via the standard** [**Orders**](#orders) **endpoints** with `deferred: true` + `side: Sell` (responses carry `deferred: true`); it is not a separate placement endpoint. Only the following are deferred-specific:

| Endpoint                                    | Contract relationship                        | Effect                                                            |
| ------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------- |
| `POST /api/v1/deferred-sell/repay/calldata` | Encodes `StockRouter.repayDeferredStockDebt` | Returns repay tx data                                             |
| `POST /api/v1/deferred-sell/repay/send`     | OneClickRouter forwards repay                | Repays debt and auto-records tx (`operationType: deferred_repay`) |
| `GET /api/v1/deferred-sell/debts`           | Indexed deferred-sell debt state             | Lists outstanding debt per stock for the bound user               |

Deferred sell creates a debt equal to the filled quantity (`DeferredSellDebtIncreased`); repayment reduces it (`DeferredSellDebtRepaid`). A partner that is `restricted` is also blocked from stock withdrawals on-chain.

Repay (`repayDeferredStockDebt`) transfers the stock from the partner's **wallet** (ERC-20 `transferFrom`, so the wallet must approve `StockRouter`) and burns it — it does not consume `exchangeBalance`. Stock held in `exchangeBalance` must be withdrawn to the wallet first.

## Cash

| Endpoint                                     | Contract relationship              | Effect                             |
| -------------------------------------------- | ---------------------------------- | ---------------------------------- |
| `POST /api/v1/cash/deposits/calldata`        | Encodes `StockRouter.deposit`      | Returns deposit tx data            |
| `POST /api/v1/cash/deposits/send`            | OneClickRouter forwards deposit    | Deposits from bound user           |
| `POST /api/v1/cash/deposits/tx`              | API/indexer mapping                | Links self-submitted deposit tx    |
| `GET /api/v1/cash/deposits`                  | Indexed Cashier state              | Lists deposits                     |
| `GET /api/v1/cash/deposits/{operationId}`    | Cash operation state               | Deposit detail and status          |
| `POST /api/v1/cash/withdrawals/calldata`     | Encodes `StockRouter.withdraw`     | Returns withdrawal tx data         |
| `POST /api/v1/cash/withdrawals/send`         | OneClickRouter forwards withdrawal | Withdraws from bound user          |
| `POST /api/v1/cash/withdrawals/tx`           | API/indexer mapping                | Links self-submitted withdrawal tx |
| `GET /api/v1/cash/withdrawals`               | Indexed Cashier state              | Lists withdrawals                  |
| `GET /api/v1/cash/withdrawals/{operationId}` | Cash operation state               | Withdrawal detail and status       |

## Stock

| Endpoint                                      | Contract relationship                    | Effect                                   |
| --------------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| `POST /api/v1/stock/deposits/calldata`        | Encodes `StockRouter.depositStock`       | Returns stock deposit tx data            |
| `POST /api/v1/stock/deposits/send`            | OneClickRouter forwards stock deposit    | Deposits stock from bound user           |
| `POST /api/v1/stock/deposits/tx`              | API/indexer mapping                      | Links self-submitted stock deposit tx    |
| `GET /api/v1/stock/deposits`                  | Indexed Stock state                      | Lists stock deposits                     |
| `GET /api/v1/stock/deposits/{operationId}`    | Stock operation state                    | Stock deposit detail                     |
| `POST /api/v1/stock/withdrawals/calldata`     | Encodes `StockRouter.withdrawStock`      | Returns stock withdrawal tx data         |
| `POST /api/v1/stock/withdrawals/send`         | OneClickRouter forwards stock withdrawal | Withdraws stock from bound user          |
| `POST /api/v1/stock/withdrawals/tx`           | API/indexer mapping                      | Links self-submitted stock withdrawal tx |
| `GET /api/v1/stock/withdrawals`               | Indexed Stock state                      | Lists stock withdrawals                  |
| `GET /api/v1/stock/withdrawals/{operationId}` | Stock operation state                    | Stock withdrawal detail                  |

For stock deposit and withdrawal detail endpoints, `operationId` is an API/indexer lookup identifier. It is not emitted as a native field by `Stock.depositStock` or `Stock.withdrawStock` events.

## One Click

| Endpoint                   | Contract relationship                  | Effect                 |
| -------------------------- | -------------------------------------- | ---------------------- |
| `GET /api/v1/1ct/status`   | Reads OneClickRouter delegate state    | Shows delegation state |
| `POST /api/v1/1ct/prepare` | Builds EIP-712 delegate payload        | No state change        |
| `POST /api/v1/1ct/enable`  | Calls `delegateBySig` through operator | Enables delegatee      |
| `POST /api/v1/1ct/disable` | Calls undelegate flow                  | Disables delegation    |

## Invariants for Integrators

* API calldata targets `StockRouter`; do not call Cashier or Stock directly.
* Buy orders lock `mUSD` in Cashier.
* Plain sell orders lock `Stock.stockBalance`, surfaced by the API as `exchangeBalance`.
* Order settlement updates `mUSD` and `exchangeBalance` asynchronously after execution.
* Cash operations can be instant or queued depending on Cashier buffers.


# Enums & Constraints

## Header enums

| Field            | Allowed values                                   |
| ---------------- | ------------------------------------------------ |
| `x-api-chain-id` | `8453`, `1`, `143`, `11155111`, `10143`, `84532` |
| `x-api-p`        | `Anchored`                                       |

## Permission enums

| Field    | Values      | Description        |
| -------- | ----------- | ------------------ |
| `access` | `READ_ONLY` | GET only.          |
| `access` | `WRITABLE`  | GET, POST, DELETE. |

## Order enums

| Field           | Values                                                                              | Description                                                                                                                                                                    |
| --------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `side`          | `Buy`, `Sell`                                                                       | Direction.                                                                                                                                                                     |
| `type`          | `Market`, `Limit`                                                                   | Order type.                                                                                                                                                                    |
| `timeInForce`   | `DAY`                                                                               | Limit TIF. The contract enum includes `GTC`, `OPG`, `IOC`, `FOK`, `GTX`, `GTD`, and `CLS` for forward compatibility, but current production contracts reject non-`DAY` values. |
| `operationType` | `trade`, `deposit`, `withdraw`, `stock_deposit`, `stock_withdraw`, `deferred_repay` | Order-tx mapping type. Deferred **sells** are recorded as `trade` (they are regular orders); only debt **repay** uses `deferred_repay`.                                        |

> Production limit orders currently only accept `DAY`; other `timeInForce` values will make the order transaction revert.

### Order status (mapped)

| Value            | Description             |
| ---------------- | ----------------------- |
| `Init`           | Initial.                |
| `Pending`        | Recorded or processing. |
| `New`            | New order identified.   |
| `Partial filled` | Partial fill.           |
| `Filled`         | Filled.                 |
| `Canceled`       | Canceled.               |
| `Expired`        | Expired.                |
| `Rejected`       | Rejected.               |
| `Failed`         | Failed.                 |

### On-chain status

| Value       | Description       |
| ----------- | ----------------- |
| `placing`   | Processing.       |
| `canceling` | Cancel in flight. |

### Broker raw status

```
init, pending, failed, new, partially_filled, filled, done_for_day,
canceled, expired, replaced, pending_cancel, pending_replace, accepted,
pending_new, accepted_for_bidding, stopped, rejected, suspended, calculated
```

## Cash status

### operationStatus

| Value        | Description |
| ------------ | ----------- |
| `requested`  | Requested.  |
| `processing` | Processing. |
| `settled`    | Settled.    |
| `closed`     | Closed.     |

### mappingStatus

Same as order mapping status enum above.

## Market data enums

### K-line interval

| Value | Description |
| ----- | ----------- |
| `1m`  | 1 minute    |
| `3m`  | 3 minutes   |
| `5m`  | 5 minutes   |
| `15m` | 15 minutes  |
| `1h`  | 1 hour      |
| `1d`  | 1 day       |
| `1w`  | 1 week      |

### Adjustment type

| Value      | Description    |
| ---------- | -------------- |
| `raw`      | No adjustment. |
| `split`    | Split.         |
| `dividend` | Dividend.      |
| `spin-off` | Spin-off.      |
| `all`      | All (default). |

### Corporate action types

| Value             | Description     |
| ----------------- | --------------- |
| `reverse_splits`  | Reverse split.  |
| `forward_splits`  | Forward split.  |
| `unit_splits`     | Unit split.     |
| `stock_dividends` | Stock dividend. |
| `cash_dividends`  | Cash dividend.  |

## Value constraints

| Field          | Constraint                                                                                                                       |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `stockAddress` | Valid EVM address. Lowercased by server.                                                                                         |
| `userAddress`  | Valid EVM address.                                                                                                               |
| `tokenAddress` | Valid EVM address.                                                                                                               |
| `quantity`     | > 0 in API input. Stock order quantities must encode to an 18-decimal WAD multiple of `1e9` (broker-facing 9-decimal precision). |
| `notional`     | > 0. Market-buy USD amount must use the production USD step: `0.01` when amount is `>= 1`, or `0.0001` when amount is `< 1`.     |
| `price`        | > 0. Limit price must use the production USD step: `0.01` when price is `>= 1`, or `0.0001` when price is `< 1`.                 |
| `tokenAmount`  | > 0, decimals ≤ token decimals, raw ≤ uint96.                                                                                    |
| `creditAmount` | > 0, up to 18 decimals, raw ≤ uint96.                                                                                            |
| `deadline`     | Unix seconds, > 0, ≤ `4294967295`.                                                                                               |
| `orderId`      | bytes32 hex (64 chars) for cancel.                                                                                               |
| `signature`    | 65-byte hex for One Click enable.                                                                                                |
| `gasLimit`     | Optional; server estimates if empty or ≤ 0.                                                                                      |


# Environments & Chains

Use this page to choose the correct base URL, chain ID, product type, and spender assumptions. These docs focus the Anchored RWA API.

## Base URL

Production Trading API:

```
https://rwa-api.anchored.finance/rwa/trading
```

All endpoint paths start with `/api/v1`.

HMAC authentication uses the path only:

```
/api/v1/symbols
```

Do not sign the domain or `/rwa/trading` prefix.

## Product Context

Every request must include both:

| Header           | Meaning                                               |
| ---------------- | ----------------------------------------------------- |
| `x-api-chain-id` | Chain context for the request                         |
| `x-api-p`        | Product context. Use `Anchored` for the Anchored API. |

The API key must have a matching `chainId + productType + access` permission.

## Supported Chain IDs

| Chain ID   | Chain            |
| ---------- | ---------------- |
| `8453`     | Base Mainnet     |
| `1`        | Ethereum Mainnet |
| `143`      | Monad Mainnet    |
| `11155111` | Ethereum Sepolia |
| `10143`    | Monad Testnet    |
| `84532`    | Base Sepolia     |

## Mainnet Contract Addresses

Anchored production uses the same deterministic proxy addresses on Base, Monad, and Ethereum:

| Contract         | Address                                      |
| ---------------- | -------------------------------------------- |
| `StockRouter`    | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |
| `Cashier`        | `0x8c1b182bb0fe4e8407404ffe37c974d6dacef3a9` |
| `Stock`          | `0x6d202d2f78aa26a7db51491416abf7f7a5003aac` |
| `OneClickRouter` | `0x102c30ac544aed8cbf838fdc1b1677ff16df0e65` |

## Mainnet Cash Tokens and Approval Spenders

| Chain ID | Chain            | Cash token                                   | Approval spender (`StockRouter`)             |
| -------- | ---------------- | -------------------------------------------- | -------------------------------------------- |
| `8453`   | Base Mainnet     | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |
| `143`    | Monad Mainnet    | `0x754704Bc059F8C67012fEd69BC8A327a5aafb603` | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |
| `1`      | Ethereum Mainnet | `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` | `0x4f090d817fd83753988a7b0c1d76f170f8461be8` |

Production cash config from `anchored-contracts` `config/production`:

| Config                     | Value                    |
| -------------------------- | ------------------------ |
| Deposit rate               | `1`                      |
| Withdrawal rate            | `0.9979`                 |
| Minimum amount             | `90` cash-token units    |
| `creditBufferCapacity`     | `20000` `mUSD`           |
| `withdrawalBufferCapacity` | `10000` cash-token units |
| `instantThresholdDivisor`  | `5`                      |

## Request Context Checklist

Before sending state-changing requests, confirm:

| Item             | Expected                                       |
| ---------------- | ---------------------------------------------- |
| Base URL         | `https://rwa-api.anchored.finance/rwa/trading` |
| HMAC URI         | `/api/v1/...` only                             |
| `x-api-chain-id` | Matches wallet network                         |
| `x-api-p`        | Exact product value                            |
| API key scope    | Allows requested chain/product/access          |
| Deposit spender  | Matches chain/product                          |
| Wallet allowance | Sufficient before deposit                      |

## Common Mismatches

| Mismatch                    | Symptom                         | Fix                                        |
| --------------------------- | ------------------------------- | ------------------------------------------ |
| Wallet on wrong chain       | Tx fails or hits wrong contract | Switch wallet to `x-api-chain-id`          |
| API key lacks product scope | `Unauthorized`                  | Grant correct `chainId + x-api-p + access` |
| Wrong `x-api-p` casing      | `Unsupported product`           | Use exact `Anchored`                       |
| Wrong spender               | Deposit tx reverts              | Use spender for chain/product              |
| Wrong HMAC URI              | `Unauthorized`                  | Authenticate `/api/v1/...` only            |


# Status Model

This page explains how to interpret order and cash operation states.

## Order State Model

```mermaid
flowchart TB
    A[Build calldata or send] --> B[Tx submitted]
    B --> C[Tx mapping]
    C --> D[Order ID backfilled]
    D --> E{Order type}
    E -->|Market| F[placing]
    E -->|Limit| G[placing or open]
    F --> H[Execution result]
    G --> I{Fill or cancel}
    I -->|fill| H
    I -->|cancel| J[canceling]
    H --> K[historyOrder]
    J --> K
```

## API Objects

| Object         | Meaning                                               | Integration use                            |
| -------------- | ----------------------------------------------------- | ------------------------------------------ |
| `mapping`      | API key to tx/order linkage                           | Transaction accepted / waiting for indexer |
| `openOrder`    | On-chain order still active or canceling              | Open order or cancel in progress           |
| `historyOrder` | Settled, canceled, rejected, expired, or failed order | Final result                               |

## Order Statuses

| Status           | Meaning                             | Suggested handling |
| ---------------- | ----------------------------------- | ------------------ |
| `Init`           | Mapping or order initialized        | Pending            |
| `Pending`        | Processing                          | Pending            |
| `New`            | Order recognized                    | Open               |
| `Partial filled` | Some quantity filled                | Partially filled   |
| `Filled`         | Fully filled                        | Filled             |
| `Canceled`       | Canceled                            | Canceled           |
| `Expired`        | Expired by TIF/execution rules      | Expired            |
| `Rejected`       | Rejected by execution or validation | Failed / rejected  |
| `Failed`         | Processing failed                   | Failed             |

On-chain transient statuses:

| Status      | Meaning                   | Suggested handling |
| ----------- | ------------------------- | ------------------ |
| `placing`   | Order placement is active | Placing            |
| `canceling` | Cancel request is active  | Canceling          |

## Market Order Expectations

Market orders are intended for immediate execution, but settlement is still async.

```mermaid
flowchart LR
    A[Market order placed] --> B[Execution result]
    B --> C{Fill size}
    C -->|full| D[Filled]
    C -->|partial| E[Partial filled plus refund]
    C -->|zero| F[No fill plus refund]
```

Integration guidance:

* Do not show market order as final at tx mining time.
* Treat `placing` as pending until settlement appears.
* Refresh portfolio after final status.

## Limit Order Expectations

Limit orders can remain open.

```mermaid
flowchart TB
    A[Limit order placed] --> B[Open]
    B --> C{Execution event}
    C -->|fill| D[Filled or partial]
    C -->|cancel request| E[Canceling]
    C -->|expiry| F[Expired]
    E --> G[Canceled or partial cancel settlement]
```

Integration guidance:

* Show open limit orders separately from final history.
* Allow cancel only for open limit orders that are not already canceling.
* Current production contracts accept only `DAY` limit orders; treat expiry/fill/cancel transitions as asynchronous backend and settlement behavior after the order is placed.

## Cash Operation State Model

Cash operations use Cashier buffers for instant settlement when possible. If the relevant buffer cannot cover the operation safely, the operation follows the queued settlement path. See [../cash/buffer-mechanism.md](/trading-api/cash-operations/buffer-mechanism).

```mermaid
flowchart TB
    A[Cash request tx] --> B[Mapping]
    B --> C[Operation created]
    C --> D{Instant buffer}
    D -->|available| E[settled]
    D -->|not available| F[processing]
    F --> G[Final cash settlement]
    G --> E
    E --> H[Portfolio updated]
```

## Cash Statuses

| `operationStatus` | Meaning                         | Suggested handling |
| ----------------- | ------------------------------- | ------------------ |
| `requested`       | Operation created               | Requested          |
| `processing`      | Waiting on settlement path      | Processing         |
| `settled`         | `mUSD` applied or cash paid out | Complete           |
| `closed`          | Closed lifecycle                | Closed             |

`mappingStatus` reuses the order mapping status enum. Use it to explain whether the tx was recorded and recognized.

## Portfolio Refresh Rules

Refresh portfolio after:

* Deposit operation reaches `settled`.
* Withdrawal operation reaches `settled` or `closed`.
* Order moves from `openOrder` to `historyOrder`.
* Cancel settlement completes.

Treat the status endpoint as authoritative for lifecycle and the portfolio endpoint as authoritative for balances.


# Sample Responses

These examples are representative. Use the live OpenAPI snapshot for exact schema names and the API response for production values.

## Unified Envelope

```json
{
  "code": 200,
  "errMsg": "",
  "data": {},
  "uuid": "b3d8d0b5-2f93-4f4e-bf06-2f0e5a9f6d1f",
  "t": 1782390000000
}
```

## Symbols

```json
{
  "code": 200,
  "errMsg": "",
  "data": [
    {
      "symbol": "AAPL",
      "contractAddress": "0x3333333333333333333333333333333333333333",
      "contractSymbol": "aAAPL",
      "contractName": "Anchored Apple Inc.",
      "decimals": 18,
      "onChainDecimals": 18,
      "tradable": true,
      "fractionable": true,
      "overnightTradable": false,
      "fractionalEhEnabled": false,
      "price": 180.5,
      "change24H": 1.2,
      "change24HPercent": 0.67,
      "logoUrl": "https://example.com/aapl.png",
      "lastUpdateTimestamp": 1782390000,
      "name": "Apple Inc.",
      "pdfUrl": "https://example.com/aapl.pdf",
      "volume24H": 1234567
    }
  ],
  "uuid": null,
  "t": null
}
```

## Portfolio Balance

```json
{
  "code": 200,
  "errMsg": "",
  "data": {
    "chainId": 143,
    "productType": "Anchored",
    "address": "0x1111111111111111111111111111111111111111",
    "mUsdBalance": "100.00",
    "tokenBalances": [
      {
        "address": "0x2222222222222222222222222222222222222222",
        "name": "USD Coin",
        "symbol": "USDC",
        "stockSymbol": null,
        "isStock": false,
        "decimals": 6,
        "price": null,
        "walletBalance": "250.00",
        "walletAllowance": "1000.00",
        "exchangeBalance": "0",
        "logoUrl": "https://example.com/usdc.png"
      },
      {
        "address": "0x3333333333333333333333333333333333333333",
        "name": "Anchored Apple Inc.",
        "symbol": "aAAPL",
        "stockSymbol": "AAPL",
        "isStock": true,
        "decimals": 18,
        "price": 180.5,
        "walletBalance": "0.25",
        "walletAllowance": "0",
        "exchangeBalance": "1.50",
        "logoUrl": "https://example.com/aapl.png"
      }
    ]
  },
  "uuid": null,
  "t": null
}
```

Interpretation:

* `mUsdBalance` is `mUSD` for buys and withdrawals.
* `walletBalance` is wallet-held ERC-20.
* `exchangeBalance` is the API view of `Stock.stockBalance`, used by plain sells.
* `walletAllowance` matters before deposits.

## Order Calldata

```json
{
  "code": 200,
  "errMsg": "",
  "data": {
    "chainId": 143,
    "productType": "Anchored",
    "toAddress": "0x4444444444444444444444444444444444444444",
    "value": "0",
    "callData": "0xabcdef...",
    "method": "placeMarketOrder"
  },
  "uuid": null,
  "t": null
}
```

Submit `toAddress`, `value`, and `callData` exactly as returned.

## Order Detail

```json
{
  "code": 200,
  "errMsg": "",
  "data": {
    "openOrder": null,
    "historyOrder": {
      "orderId": "0x0000000000000001000200001111111111111111111111111111111111111111",
      "userAddress": "0x1111111111111111111111111111111111111111",
      "side": "Buy",
      "type": "Market",
      "tif": null,
      "symbol": "AAPL",
      "placeNotional": "10.00",
      "placeQuantity": null,
      "pay": "10.00",
      "placePrice": null,
      "status": "Filled",
      "settleTxHash": "0xdef...",
      "settlePrice": "180.50",
      "settlePay": "9.95",
      "settleReceive": "0.0551",
      "mintFee": "0.01",
      "protocolFee": "0.01"
    }
  },
  "uuid": null,
  "t": null
}
```

## Deposit Detail

```json
{
  "code": 200,
  "errMsg": "",
  "data": {
    "mappingStatus": "Filled",
    "operationStatus": "settled",
    "mapping": {
      "txHash": "0xabc...",
      "operationType": "deposit"
    },
    "depositOperation": {
      "operationId": "0x1234...",
      "userAddress": "0x1111111111111111111111111111111111111111",
      "tokenAddress": "0x2222222222222222222222222222222222222222",
      "status": "settled",
      "isInstant": true,
      "amount": 100,
      "creditAmount": 100,
      "feeAmount": 0,
      "createTxHash": "0xabc...",
      "settleTxHash": "0xdef..."
    },
    "withdrawalOperation": null
  },
  "uuid": null,
  "t": null
}
```

## One Click Status

```json
{
  "code": 200,
  "errMsg": "",
  "data": {
    "status": "enable",
    "delegatee": "0x5555555555555555555555555555555555555555"
  },
  "uuid": null,
  "t": null
}
```

## Error Response

```json
{
  "code": 401,
  "errMsg": "Unauthorized",
  "data": null,
  "uuid": "b3d8d0b5-2f93-4f4e-bf06-2f0e5a9f6d1f",
  "t": 1782390000000
}
```

Use `uuid` when escalating issues.

## Market config

```json
{
  "code": 200,
  "data": {
    "cashierBuffer": {
      "chain": 10143,
      "productType": "MondayTrade",
      "address": "0x....",
      "instantThresholdDivisor": "1",
      "creditBuffer": "743810467000000000000",
      "creditBufferCapacity": "1000000000000000000000",
      "totalBalance": "156027003229608600000"
    },
    "exchangeFeeConfig": {
      "chainId": 10143,
      "productType": "MondayTrade",
      "mintFeeRate": "0",
      "protocolFeeRate": "0",
      "minOrderValue": "0",
      "txHash": "",
      "updatedAt": 1778477709
    },
    "cashierTokenConfig": {
      "0x534b2f3a21130d7a60830c2df862319e593943a3": {
        "chain": 10143,
        "productType": "MondayTrade",
        "cashierAddress": "0x....",
        "tokenAddress": "0x534b2f3a21130d7a60830c2df862319e593943a3",
        "minAmount": "1",
        "decimals": 6,
        "depositPaused": false,
        "withdrawPaused": false,
        "depositRate": "1",
        "withdrawalBuffer": "253689533",
        "withdrawalBufferCapacity": "1000000000",
        "withdrawalRate": "0.9969"
      }
    }
  },
  "errMsg": "",
  "t": null,
  "uuid": null
}

```

> Field names in `cashierBuffer` match the live OpenAPI schema (`CashierBufferRespDto`).


# Troubleshooting

Use this guide when an API request fails, a transaction reverts, or an order/cash operation appears stuck.

## First Triage

Start with the layer where the failure appears:

1. If API `code` is not `200`, fix request auth, scope, or parameters first.
2. If API succeeds but no transaction is submitted, inspect the calldata response and wallet client.
3. If the transaction is submitted but reverts, debug allowance, balance, deadline, chain, and router target.
4. If the transaction succeeds but the API cannot find it, record `txHash` or wait for indexer backfill.
5. If mapping exists but state is not final, poll order or cash detail endpoints.

## API Auth Fails

Symptoms:

* HTTP `400` with `code: 401`
* `Unauthorized`
* Signature, nonce, timestamp, IP, or permission errors

All of these return the **same** `401 Unauthorized` — the response body does **not** say which one failed. Rule them out one by one; for a new integration, check the IP whitelist and timestamp first.

| Check                                 | Fix                                                                                                                                                  |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| API key invalid, inactive, or expired | Confirm the key exists, is `active`, and `expires_at` is unset or future                                                                             |
| Empty or mismatched IP whitelist      | Add your egress IP ([headers-and-permissions.md](/trading-api/authentication/headers-and-permissions)); an empty whitelist rejects everything        |
| `x-api-ts` outside 45-second window   | Use current UTC milliseconds                                                                                                                         |
| Reused `x-api-nonce`                  | Use a unique UUID per request                                                                                                                        |
| Wrong HMAC URI                        | Authenticate `/api/v1/...`, not the full URL                                                                                                         |
| Literal `\n` in signed payload        | Join the 5 lines with **real newlines**, not the two-character `\n` (a common shell bug — see [signature.md](/trading-api/authentication/signature)) |
| Query order mismatch                  | Sort query params by name before HMAC authentication                                                                                                 |
| Body mismatch                         | Sign the exact JSON string sent                                                                                                                      |
| Missing scope                         | Confirm `chainId + productType + access` permission                                                                                                  |

## Order Rejected Before Calldata Is Built

The API rejects some orders up front (non-`200`, before any transaction), so a bad order never reaches the chain. These apply to both `/calldata` and `/send`:

| Message                                                                                  | Cause                                                                                                                           | Fix                                                    |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| `market order is only supported during the regular trading session (current: <session>)` | Market order (incl. deferred market sell) placed outside the regular US session (pre-market / after-hours / overnight / closed) | Wait for the regular session, or use a **limit** order |
| `deferred sell is not allowed for this address` / `... is restricted ...`                | Address not whitelisted (`allowed && !restricted`) for deferred sell                                                            | Have the deferred-sell manager configure the address   |
| `timeInForce only supports DAY ...`                                                      | Limit order with non-`DAY` TIF                                                                                                  | Use `timeInForce: "DAY"`                               |

## Calldata Builds But Chain Transaction Reverts

Common causes:

| Symptom                                       | Likely cause                                                                                            | Fix                                                                                            |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Deposit tx reverts                            | Insufficient ERC-20 allowance                                                                           | Check `walletAllowance`; approve spender                                                       |
| Deposit tx reverts                            | Wallet token balance too low                                                                            | Check `walletBalance`                                                                          |
| Order tx reverts                              | Plain buy has insufficient `mUsdBalance`                                                                | Deposit first, use `/orders/with-deposit/*` when eligible, or reduce `notional`                |
| Sell tx reverts                               | Plain sell has insufficient `exchangeBalance`, or order-with-deposit sell lacks stock allowance/balance | Approve stock, use `/orders/with-deposit/*`, or reduce quantity                                |
| Cancel tx reverts                             | Order not open or already canceling                                                                     | Query `/orders/{orderId}` first                                                                |
| Tx reverts out-of-gas (`gasUsed == gasLimit`) | Default `estimateGas` is too low on some chains (e.g. Monad) for router calls                           | Self-submit: add a gas buffer (`estimateGas × 1.5–2`). One Click: pass a sufficient `gasLimit` |
| Deadline error                                | `deadline` expired                                                                                      | Use a future Unix seconds value                                                                |
| Wrong chain                                   | Wallet on different chain than `x-api-chain-id`                                                         | Switch wallet network                                                                          |

## Deposit Not Credited Yet

A mined deposit transaction still needs API mapping and, for queued deposits, final cash settlement before `mUsdBalance` updates.

If the transaction succeeded:

1. Confirm `POST /api/v1/cash/deposits/tx` was called with the correct `txHash`.
2. Poll `GET /api/v1/cash/deposits/{operationId}`.
3. Check `operationStatus`.
4. Refresh `GET /api/v1/users/{userId}/balance`.

Queued deposits can remain `processing` while final cash settlement is still pending.

## Withdrawal Not Paid Out Yet

Withdrawals can be instant or queued. If queued:

1. `mUSD` is deducted first.
2. Final cash settlement completes later.
3. Cashier transfers tokens to the user when settlement completes.

Poll:

```
GET /api/v1/cash/withdrawals/{operationId}
```

Do not treat `processing` as failed unless the operation has an explicit failure status or support confirms an issue.

## Order Tx Mined But No Order ID

This usually means the indexer has not backfilled the mapping yet.

Check:

```
GET /api/v1/orders/tx/{txHash}
```

If missing:

1. Confirm the tx was sent to the returned `toAddress`.
2. Confirm the tx succeeded on the same chain as `x-api-chain-id`.
3. Confirm `POST /api/v1/orders/tx` was called by the same API key.
4. Wait for indexer backfill and retry.

## Order Open Too Long

For limit orders, open state can be normal. Practical lifecycle rules depend on `timeInForce` and backend execution.

> Production limit orders currently only accept `DAY`; other `timeInForce` values will make the order transaction revert.

For market orders, long open time usually means one of:

* Execution result not yet received.
* Final order result has not settled on-chain.
* Indexer/API has not refreshed status.

Use:

```
GET /api/v1/orders/{orderId}
```

Then inspect `openOrder.status` and history fields.

## One Click Send Fails

Check:

| Check                              | Fix                                                  |
| ---------------------------------- | ---------------------------------------------------- |
| `/1ct/status` is not `enable`      | Run prepare/sign/enable flow                         |
| API key has no bound `userAddress` | Configure API key user binding                       |
| Signer mismatch                    | EIP-712 signer must equal `signPayload.message.user` |
| Expired deadline                   | Prepare and sign a fresh payload                     |
| Deposit send fails                 | Bound user must approve cash token spender           |

## Escalation Data

When escalating to backend/support, include:

* Environment base URL
* `x-api-chain-id`
* `x-api-p`
* API response `code`, `errMsg`, `uuid`, `t`
* `txHash`
* `orderId` or `operationId`
* Wallet address / `userId`
* Request path and body (without API secret)


# Integration Test Checklist

Use this checklist before granting production access or enabling real user trading.

## Test Accounts and Scope

| Check                   | Expected                                |
| ----------------------- | --------------------------------------- |
| API key active          | Requests authenticate successfully      |
| IP whitelist configured | Requests only work from approved IPs    |
| `READ_ONLY` key         | GET works; POST/DELETE fails            |
| `WRITABLE` key          | GET/POST/DELETE work for approved scope |
| Product scope           | Only configured `x-api-p` works         |
| Chain scope             | Only configured `x-api-chain-id` works  |

## Authentication Tests

Required cases:

* Valid GET with sorted query params.
* Valid POST with exact raw body.
* Invalid timestamp older than 45 seconds.
* Duplicate nonce within the replay window.
* Body changed after signature.
* Missing `x-api-chain-id`.
* Wrong `x-api-p` casing.

Expected result: valid requests pass, and each invalid case fails with a clear auth or validation error.

## Market and Portfolio Tests

| Test                          | Expected                                                                                        |
| ----------------------------- | ----------------------------------------------------------------------------------------------- |
| `GET /config`                 | Returns `cashierBuffer`, `exchangeFeeConfig`, and `cashierTokenConfig` for scoped chain/product |
| `GET /symbols`                | Returns at least one known tradable stock                                                       |
| `GET /prices/{symbol}`        | Returns quote context                                                                           |
| `GET /corporate-action`       | Returns list or empty list without error                                                        |
| `GET /users/{userId}/balance` | Returns `mUsdBalance` and `tokenBalances`                                                       |
| `spenderAddress` query        | Returns `walletAllowance` for spender                                                           |

## Cash Tests

Required cases:

* Deposit calldata with valid `userAddress`, `tokenAddress`, `tokenAmount`.
* Deposit tx succeeds after approval.
* Deposit tx reverts or is blocked when allowance is missing.
* `POST /cash/deposits/tx` is idempotent for the same API key and tx.
* Deposit detail eventually reaches final status.
* Withdrawal calldata builds for available `mUsdBalance`.
* Withdrawal detail can be polled by `operationId`.

## Stock Movement Tests

Required cases:

* Stock deposit calldata builds for valid `userAddress`, `tokenAddress`, `tokenAmount`.
* Stock deposit tx succeeds after stock token approval.
* Stock withdrawal calldata builds for available `exchangeBalance`.
* Stock deposit and withdrawal details can be polled by `operationId`.

## Order Tests

| Test                             | Expected                                                                                                                                                                                                         |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Market buy calldata              | Returns router `toAddress`, `value`, `callData`                                                                                                                                                                  |
| Market sell calldata             | Plain sell requires sufficient `exchangeBalance`; wallet-held stock can be moved with `/stock/deposits/*` first                                                                                                  |
| Order-with-deposit buy calldata  | Requires cash token allowance and instant deposit eligibility                                                                                                                                                    |
| Order-with-deposit sell calldata | Requires stock token allowance and wallet stock balance                                                                                                                                                          |
| Limit buy calldata               | Requires `quantity`, `price`, and `timeInForce`; current production contracts accept only `DAY`                                                                                                                  |
| Limit sell calldata              | Requires `quantity`, `price`, and `timeInForce`; current production contracts accept only `DAY`. Plain sell requires sufficient `exchangeBalance`; wallet-held stock can be moved with `/stock/deposits/*` first |
| Cancel calldata                  | Works only for open limit orders                                                                                                                                                                                 |
| Record order tx                  | Backfills mapping/orderId                                                                                                                                                                                        |
| Order detail                     | Moves from open to history after settlement                                                                                                                                                                      |

Include negative tests:

* Missing `notional` for market buy.
* Missing `quantity` for market sell.
* Missing `price` for limit order.
* Non-`DAY` `timeInForce` for limit order.
* Expired `deadline`.
* Cancel market order.
* Cancel order owned by different API key.

## One Click Tests

Required cases:

* Status before enable.
* Prepare returns signer-matching `signPayload`.
* Signature by wrong wallet is rejected.
* Expired deadline is rejected.
* Enable succeeds with correct signature.
* `/send` order succeeds after enable.
* Deposit `/send` fails without token approval.
* Disable succeeds and blocks future `/send`.

## Reconciliation Tests

After each state-changing test, verify:

* API response `code` is `200`.
* Tx receipt succeeded.
* Mapping endpoint finds tx.
* Detail endpoint reaches expected state.
* Portfolio reflects final balances.
* Fees and partial fills are shown correctly when present.

## Production Readiness

Before go-live:

* Store API secrets securely.
* Log request path, response `uuid`, txHash, orderId, operationId.
* Never log API secret, wallet private key, or raw authorization material.
* Monitor delayed `processing` operations.
* Document queued cash behavior and async order settlement.
* Provide a manual support path for stuck tx/order/operation IDs.


