{
  "info": {
    "_postman_id": "a1b2c3d4-baas-4e5f-8a9b-interpose2026",
    "name": "Interpose BaaS API",
    "description": "Brokerage-as-a-Service — account lifecycle, KYC, order routing, fractional shares, custody, and real-time event streaming.\n\n**Base URL:** `{{baseUrl}}`\n\n**Auth:** Set `apiKey` in your environment for Bearer auth, or set both `apiKey` and `hmacSecret` to enable automatic HMAC-SHA256 signing via the collection pre-request script.\n\n**Environment variables required:**\n- `baseUrl` — e.g. `https://api.interposehq.com`\n- `apiKey` — your API key or Bearer token\n- `hmacSecret` — (optional) HMAC signing secret for server-to-server calls\n- `userId` — set after creating a user\n- `accountId` — set after opening an account\n- `orderId` — set after placing an order",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      { "key": "token", "value": "{{apiKey}}", "type": "string" }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "const hmacSecret = pm.environment.get('hmacSecret');",
          "if (hmacSecret) {",
          "    const timestamp = Date.now().toString();",
          "    const method = pm.request.method;",
          "    const urlObj = pm.request.url;",
          "    const path = '/' + urlObj.path.join('/');",
          "    const body = pm.request.body && pm.request.body.raw ? pm.request.body.raw : '';",
          "    const bodyHash = CryptoJS.SHA256(body).toString(CryptoJS.enc.Hex);",
          "    const canonical = method + '\\n' + path + '\\n' + timestamp + '\\n' + bodyHash;",
          "    const signature = CryptoJS.HmacSHA256(canonical, hmacSecret).toString(CryptoJS.enc.Hex);",
          "    pm.request.headers.upsert({ key: 'X-VM-Key-Id', value: pm.environment.get('apiKey') });",
          "    pm.request.headers.upsert({ key: 'X-VM-Timestamp', value: timestamp });",
          "    pm.request.headers.upsert({ key: 'X-VM-Signature', value: signature });",
          "}"
        ]
      }
    }
  ],
  "variable": [
    { "key": "baseUrl", "value": "https://api.interposehq.com", "type": "string" },
    { "key": "apiKey", "value": "your-api-key-here", "type": "string" },
    { "key": "hmacSecret", "value": "", "type": "string" },
    { "key": "userId", "value": "usr_01HV4Y2K3M5N8P9QR2ST4UVWXY", "type": "string" },
    { "key": "accountId", "value": "acct_01HV4Y2K3M5N8P9QR2ST4UVWXY", "type": "string" },
    { "key": "orderId", "value": "ord_01HV4Y2K3M5N8P9QR2ST4UVWXY", "type": "string" }
  ],
  "item": [
    {
      "name": "Users & KYC",
      "item": [
        {
          "name": "Create User (initiate KYC)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 201) {",
                  "    const body = pm.response.json();",
                  "    pm.environment.set('userId', body.user_id);",
                  "    pm.test('user_id set', () => pm.expect(body.user_id).to.be.a('string'));",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"first_name\": \"Jane\",\n  \"last_name\": \"Smith\",\n  \"email\": \"jane.smith@example.com\",\n  \"date_of_birth\": \"1985-04-12\",\n  \"phone\": \"+12125551234\",\n  \"address_line1\": \"123 Main St\",\n  \"city\": \"New York\",\n  \"state\": \"NY\",\n  \"postal_code\": \"10001\",\n  \"country\": \"US\",\n  \"citizenship\": \"US\",\n  \"ssn_last4\": \"1234\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/users",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "users"]
            },
            "description": "Create a user and initiate KYC verification. KYC decision target: <2 minutes."
          }
        },
        {
          "name": "Get User",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/users/{{userId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "users", "{{userId}}"]
            },
            "description": "Get user by ID."
          }
        },
        {
          "name": "Get KYC Status",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/users/{{userId}}/kyc",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "users", "{{userId}}", "kyc"]
            },
            "description": "Get KYC verification status. Status: PENDING | APPROVED | REJECTED | NEEDS_REVIEW."
          }
        },
        {
          "name": "Upload KYC Document",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"document_type\": \"passport\",\n  \"file_url\": \"https://your-storage.example.com/docs/passport-scan.jpg\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/users/{{userId}}/kyc/documents",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "users", "{{userId}}", "kyc", "documents"]
            },
            "description": "Upload a KYC identity document (passport, drivers_license, ssn_card). Returns 202 Accepted."
          }
        }
      ]
    },
    {
      "name": "Accounts",
      "item": [
        {
          "name": "Open Account",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 201) {",
                  "    const body = pm.response.json();",
                  "    pm.environment.set('accountId', body.account_id);",
                  "    pm.test('account_id set', () => pm.expect(body.account_id).to.be.a('string'));",
                  "    pm.test('cash_balance is 4dp string', () => {",
                  "        pm.expect(body.cash_balance).to.match(/^-?\\d+\\.\\d{4}$/);",
                  "    });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"user_id\": \"{{userId}}\",\n  \"type\": \"INDIVIDUAL\",\n  \"currency\": \"USD\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/accounts",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "accounts"]
            },
            "description": "Open a brokerage account. Types: INDIVIDUAL | JOINT | IRA_TRADITIONAL | IRA_ROTH | CUSTODIAL."
          }
        },
        {
          "name": "List Accounts",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/accounts?user_id={{userId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "accounts"],
              "query": [
                { "key": "user_id", "value": "{{userId}}" },
                { "key": "status", "value": "ACTIVE", "disabled": true }
              ]
            }
          }
        },
        {
          "name": "Get Account",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/accounts/{{accountId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "accounts", "{{accountId}}"]
            }
          }
        },
        {
          "name": "Update Account Status",
          "request": {
            "method": "PATCH",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"RESTRICTED\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/accounts/{{accountId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "accounts", "{{accountId}}"]
            },
            "description": "Update account status. Status: PENDING | ACTIVE | RESTRICTED | CLOSED."
          }
        },
        {
          "name": "Get Account Positions",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/accounts/{{accountId}}/positions",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "accounts", "{{accountId}}", "positions"]
            },
            "description": "Get all positions for an account. Quantities are 8dp strings; market values are 4dp strings."
          }
        }
      ]
    },
    {
      "name": "Orders",
      "item": [
        {
          "name": "Submit Market Order",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 201) {",
                  "    const body = pm.response.json();",
                  "    pm.environment.set('orderId', body.order_id);",
                  "    pm.test('quantity is 8dp string', () => {",
                  "        pm.expect(body.quantity).to.match(/^\\d+\\.\\d{8}$/);",
                  "    });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"account_id\": \"{{accountId}}\",\n  \"security\": {\n    \"type\": \"ticker\",\n    \"value\": \"AAPL\"\n  },\n  \"side\": \"BUY\",\n  \"type\": \"MARKET\",\n  \"quantity\": \"10.00000000\",\n  \"currency\": \"USD\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/orders",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "orders"]
            },
            "description": "Submit a market order. Runs 5 synchronous compliance checks (Reg-T, PDT, Reg SHO, wash sale) before accepting."
          }
        },
        {
          "name": "Submit Limit Order",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"account_id\": \"{{accountId}}\",\n  \"security\": {\n    \"type\": \"ticker\",\n    \"value\": \"AAPL\"\n  },\n  \"side\": \"BUY\",\n  \"type\": \"LIMIT\",\n  \"quantity\": \"10.00000000\",\n  \"limit_price\": \"185.5000\",\n  \"currency\": \"USD\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/orders",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "orders"]
            },
            "description": "Submit a limit order. limit_price must be a 4dp string."
          }
        },
        {
          "name": "List Orders",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/orders?account_id={{accountId}}&limit=50",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "orders"],
              "query": [
                { "key": "account_id", "value": "{{accountId}}" },
                { "key": "status", "value": "FILLED", "disabled": true },
                { "key": "limit", "value": "50" }
              ]
            }
          }
        },
        {
          "name": "Get Order",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/orders/{{orderId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "orders", "{{orderId}}"]
            }
          }
        },
        {
          "name": "Cancel Order",
          "request": {
            "method": "DELETE",
            "url": {
              "raw": "{{baseUrl}}/v1/orders/{{orderId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "orders", "{{orderId}}"]
            },
            "description": "Cancel an open order. Returns 409 if already filled or cancelled."
          }
        }
      ]
    },
    {
      "name": "Positions",
      "item": [
        {
          "name": "List Positions",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/positions?account_id={{accountId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "positions"],
              "query": [{ "key": "account_id", "value": "{{accountId}}" }]
            },
            "description": "List positions for an account. All quantity and value fields are strings."
          }
        }
      ]
    },
    {
      "name": "Funding",
      "item": [
        {
          "name": "Initiate ACH Deposit",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"account_id\": \"{{accountId}}\",\n  \"amount\": \"5000.0000\",\n  \"currency\": \"USD\",\n  \"plaid_token\": \"access-sandbox-abc123\",\n  \"memo\": \"Initial funding\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/funding/deposits",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "funding", "deposits"]
            },
            "description": "Initiate an ACH deposit via Plaid token. Returns 202 Accepted with transfer tracking ID."
          }
        },
        {
          "name": "Initiate ACH Withdrawal",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"account_id\": \"{{accountId}}\",\n  \"amount\": \"1000.0000\",\n  \"currency\": \"USD\",\n  \"plaid_token\": \"access-sandbox-abc123\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/funding/withdrawals",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "funding", "withdrawals"]
            }
          }
        },
        {
          "name": "List Transfers",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/funding/transfers?account_id={{accountId}}",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "funding", "transfers"],
              "query": [{ "key": "account_id", "value": "{{accountId}}" }]
            }
          }
        }
      ]
    },
    {
      "name": "Instruments",
      "item": [
        {
          "name": "Get Instrument",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/instruments/AAPL",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "instruments", "AAPL"]
            },
            "description": "Get instrument reference data by symbol."
          }
        },
        {
          "name": "Search Instruments",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/instruments?query=apple&limit=20",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "instruments"],
              "query": [
                { "key": "query", "value": "apple" },
                { "key": "limit", "value": "20" }
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Market Data",
      "description": "Real-time quotes, OHLCV bars, screeners, FX rates, symbol search, and security master.\n\nPrecision rules (all endpoints):\n- Price / monetary amounts → 4 decimal places (string)\n- Share / volume quantities → 8 decimal places (string)\n- FX rates → 6 decimal places (string)\n- Price change % → 8 decimal places (string)\n\nNo float values are ever used for financial fields.",
      "item": [
        {
          "name": "Get Quote",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('bid is 4dp string', () => {",
                  "  pm.expect(body.bid).to.be.a('string');",
                  "  pm.expect(body.bid.split('.')[1].length).to.equal(4);",
                  "});",
                  "pm.test('ask is 4dp string', () => {",
                  "  pm.expect(body.ask).to.be.a('string');",
                  "  pm.expect(body.ask.split('.')[1].length).to.equal(4);",
                  "});",
                  "pm.test('last is 4dp string', () => {",
                  "  pm.expect(body.last).to.be.a('string');",
                  "  pm.expect(body.last.split('.')[1].length).to.equal(4);",
                  "});",
                  "pm.test('bid_size is 8dp string', () => {",
                  "  pm.expect(body.bid_size).to.be.a('string');",
                  "  pm.expect(body.bid_size.split('.')[1].length).to.equal(8);",
                  "});",
                  "pm.test('provider field present', () => {",
                  "  pm.expect(['live', 'reference']).to.include(body.provider);",
                  "});",
                  "pm.test('quote_time is nanosecond ISO 8601', () => {",
                  "  pm.expect(body.quote_time).to.match(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{9}Z$/);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/quotes/AAPL",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "quotes", "AAPL"]
            },
            "description": "Fetch a single NBBO quote for a symbol. Returns `provider: \"live\"` when the Polygon polling cache has a fresh tick, `provider: \"reference\"` when falling back to static instrument data (sandbox default)."
          }
        },
        {
          "name": "Get Batch Quotes",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('response is array', () => pm.expect(body).to.be.an('array'));",
                  "pm.test('each quote has 4dp bid', () => {",
                  "  body.forEach(q => {",
                  "    pm.expect(q.bid).to.be.a('string');",
                  "    pm.expect(q.bid.split('.')[1].length).to.equal(4);",
                  "  });",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/quotes?symbols=AAPL,MSFT,BTC",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "quotes"],
              "query": [
                { "key": "symbols", "value": "AAPL,MSFT,BTC" }
              ]
            },
            "description": "Fetch quotes for up to 100 symbols in a single call. Comma-separated `symbols` query parameter. Unknown symbols are silently skipped."
          }
        },
        {
          "name": "Get OHLCV Bars",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('bars is array', () => pm.expect(body.bars).to.be.an('array'));",
                  "pm.test('each bar has 4dp OHLC', () => {",
                  "  body.bars.forEach(b => {",
                  "    ['open','high','low','close'].forEach(f => {",
                  "      pm.expect(b[f]).to.be.a('string');",
                  "      pm.expect(b[f].split('.')[1].length).to.equal(4);",
                  "    });",
                  "    pm.expect(b.volume.split('.')[1].length).to.equal(8);",
                  "  });",
                  "});",
                  "pm.test('bars in ascending time order', () => {",
                  "  const times = body.bars.map(b => b.bar_time);",
                  "  for (let i = 1; i < times.length; i++) {",
                  "    pm.expect(times[i] >= times[i-1]).to.be.true;",
                  "  }",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/bars/AAPL?interval=1d&range=1y",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "bars", "AAPL"],
              "query": [
                { "key": "interval", "value": "1d", "description": "Bar interval: 1m 5m 15m 30m 1h 1d 1wk 1mo" },
                { "key": "range", "value": "1y", "description": "Lookback range: 1d 5d 1mo 3mo 6mo ytd 1y 2y 5y" }
              ]
            },
            "description": "Historical and intraday OHLCV bars for charting. Bars are returned in ascending chronological order (oldest first). In sandbox, plausible simulated values are derived from the current instrument price."
          }
        },
        {
          "name": "Get Market Stats",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('symbol matches', () => pm.expect(body.symbol).to.equal('AAPL'));",
                  "pm.test('monetary fields are 4dp strings', () => {",
                  "  ['previous_close','open','bid','ask','day_low','day_high',",
                  "   'fifty_two_week_low','fifty_two_week_high'].forEach(f => {",
                  "    if (body[f] !== null && body[f] !== undefined) {",
                  "      pm.expect(body[f]).to.be.a('string');",
                  "      pm.expect(body[f].split('.')[1].length).to.equal(4);",
                  "    }",
                  "  });",
                  "});",
                  "pm.test('quote_time is nanosecond ISO 8601', () => {",
                  "  pm.expect(body.quote_time).to.match(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{9}Z$/);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/stats/AAPL",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "stats", "AAPL"]
            },
            "description": "Full market statistics including bid/ask, day range, 52-week range, volume, market cap, P/E, EPS, beta, dividends, and analyst target price."
          }
        },
        {
          "name": "Get Screener",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('quotes is array', () => pm.expect(body.quotes).to.be.an('array'));",
                  "pm.test('screen_id matches param', () => pm.expect(body.screen_id).to.equal('most_actives'));",
                  "pm.test('each row has 4dp last price', () => {",
                  "  body.quotes.forEach(r => {",
                  "    pm.expect(r.last).to.be.a('string');",
                  "    pm.expect(r.last.split('.')[1].length).to.equal(4);",
                  "    pm.expect(r.price_change).to.be.a('string');",
                  "    pm.expect(r.price_change_pct).to.be.a('string');",
                  "  });",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/screener?screen_id=most_actives&count=50",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "screener"],
              "query": [
                { "key": "screen_id", "value": "most_actives", "description": "most_actives | day_gainers | day_losers | growth_technology_stocks | undervalued_growth_stocks | aggressive_small_caps" },
                { "key": "count", "value": "50" }
              ]
            },
            "description": "Returns a ranked list of instruments for the selected preset screener. All price, change, and volume fields are decimal-precision strings."
          }
        },
        {
          "name": "Get Screener — Day Gainers",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/screener?screen_id=day_gainers&count=25",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "screener"],
              "query": [
                { "key": "screen_id", "value": "day_gainers" },
                { "key": "count", "value": "25" }
              ]
            }
          }
        },
        {
          "name": "Get FX Rates",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('rates is array', () => pm.expect(body.rates).to.be.an('array'));",
                  "pm.test('each rate is 6dp string', () => {",
                  "  body.rates.forEach(r => {",
                  "    pm.expect(r.rate).to.be.a('string');",
                  "    pm.expect(r.rate.split('.')[1].length).to.equal(6);",
                  "  });",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/fx-rates?pairs=USD:GBP,USD:EUR,USD:CAD",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "fx-rates"],
              "query": [
                { "key": "pairs", "value": "USD:GBP,USD:EUR,USD:CAD", "description": "Comma-separated BASE:QUOTE pairs. Supported: USD GBP EUR CAD AUD JPY SGD CHF HKD" }
              ]
            },
            "description": "FX rates for BASE:QUOTE currency pairs. All rates are 6 decimal place strings. Cross rates (e.g. GBP:EUR) are derived via USD when no direct rate is available."
          }
        },
        {
          "name": "Search Market",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('results is array', () => pm.expect(body.results).to.be.an('array'));",
                  "pm.test('total is number', () => pm.expect(body.total).to.be.a('number'));",
                  "pm.test('each result has symbol and name', () => {",
                  "  body.results.forEach(r => {",
                  "    pm.expect(r.symbol).to.be.a('string');",
                  "    pm.expect(r.name).to.be.a('string');",
                  "  });",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/search?q=apple&limit=20",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "search"],
              "query": [
                { "key": "q", "value": "apple", "description": "Ticker prefix or company name fragment" },
                { "key": "limit", "value": "20" }
              ]
            },
            "description": "Full-text search across ticker symbols and company names. Useful for typeahead / autocomplete in client UIs."
          }
        },
        {
          "name": "List Securities (Security Master)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('securities is array', () => pm.expect(body.securities).to.be.an('array'));",
                  "pm.test('total is number', () => pm.expect(body.total).to.be.a('number'));",
                  "pm.test('each security has boolean eligibility flags', () => {",
                  "  body.securities.forEach(s => {",
                  "    pm.expect(s.is_tradable).to.be.a('boolean');",
                  "    pm.expect(s.is_fractional_eligible).to.be.a('boolean');",
                  "    pm.expect(s.is_marginable).to.be.a('boolean');",
                  "  });",
                  "});",
                  "pm.test('min_quantity is string', () => {",
                  "  body.securities.forEach(s => {",
                  "    pm.expect(s.min_quantity).to.be.a('string');",
                  "  });",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/securities?asset_class=ALL&limit=100",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "securities"],
              "query": [
                { "key": "asset_class", "value": "ALL", "description": "ALL | EQUITY | ETF | CRYPTO | OPTION | FIXED_INCOME" },
                { "key": "limit", "value": "100" }
              ]
            },
            "description": "Full security master list with trading eligibility flags (is_tradable, is_fractional_eligible, is_marginable, is_dtc_eligible, is_shortable, is_easy_to_borrow), CUSIP/ISIN, and min_quantity. Check these flags before placing orders."
          }
        },
        {
          "name": "Get Security",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('symbol matches', () => pm.expect(body.symbol).to.equal('AAPL'));",
                  "pm.test('is_tradable is boolean', () => pm.expect(body.is_tradable).to.be.a('boolean'));",
                  "pm.test('min_quantity is string', () => pm.expect(body.min_quantity).to.be.a('string'));",
                  "pm.test('status is ACTIVE', () => pm.expect(body.status).to.equal('ACTIVE'));"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/market/securities/AAPL",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "market", "securities", "AAPL"]
            },
            "description": "Single instrument from the security master. Returns full eligibility flags, CUSIP, ISIN, sector, and min_quantity."
          }
        }
      ]
    },
    {
      "name": "Stream (WebSocket)",
      "item": [
        {
          "name": "Real-Time Event Stream",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/v1/stream",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "stream"]
            },
            "description": "WebSocket upgrade endpoint. Use a WebSocket client (Postman WebSocket tab or wscat).\n\nAfter connecting, send:\n```json\n{\"action\": \"subscribe\", \"account_id\": \"{{accountId}}\"}\n```\n\nServer pushes CloudEvents 1.0 JSON for:\n- `com.interpose.baas.order.submitted`\n- `com.interpose.baas.order.filled`\n- `com.interpose.baas.order.cancelled`\n- `com.interpose.baas.position.updated`\n- `com.interpose.post-trade.transaction.initiated`\n- `com.interpose.post-trade.transaction.settled`"
          }
        }
      ]
    }
  ]
}
