{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Call Palisade Operations Directly","siteUrl":"https://opensource.ripple.com/","meta":[{"name":"google-site-verification","content":"bLwyBi1imklcIuQxZ7JeI_kRF5Mg7yfr6arpEQV2nsE"}],"llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]},"description":"Call the Palisade API directly for any operations simpleXRPL verticals don't expose."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"call-palisade-operations-directly","__idx":0},"children":["Call Palisade Operations Directly"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Call any Palisade operation directly, using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["palisade.api"]}," escape hatch."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"/**\n * Call any Palisade operation directly — the `palisade.api` escape hatch.\n *\n * The verticals (`client.xrp`/`iou`/`token`/…) cover the operations simpleXRPL\n * models first-class. For everything else Palisade exposes — vaults,\n * counterparties, policies, webhooks, balances — reach for `palisade.api.call`,\n * a **secondary** surface keyed on the operationId. Path params, query, body,\n * and the response are all typed from the generated OpenAPI schema, so the call\n * autocompletes and type-checks without a hand-written method per resource.\n *\n * Auth routing has two layers. Method-based (the default): reads (`GET`) go on\n * the wallet-read credential, mutations on the transactions one. Tag-based\n * (optional): register a credential per Palisade permission scope under\n * `credentials.scoped` and every operation in that scope routes to it — needed\n * because Palisade scopes one permission set per credential, so policy or\n * webhook administration lives on its own credential.\n */\nimport { PalisadeCustody } from 'simplexrpl'\n\n// The same two-credential Palisade connector used by the vertical examples,\n// plus an optional scoped credential for the `Policies` permission set.\nconst palisade = await PalisadeCustody.create({\n  baseUrl: 'https://api.sandbox.palisade.co', // sandbox (TESTNET data)\n  credentials: {\n    wallets: {\n      clientId: process.env.PALISADE_WALLETS_CLIENT_ID ?? '',\n      clientSecret: process.env.PALISADE_WALLETS_CLIENT_SECRET ?? '',\n    },\n    transactions: {\n      clientId: process.env.PALISADE_TX_CLIENT_ID ?? '',\n      clientSecret: process.env.PALISADE_TX_CLIENT_SECRET ?? '',\n    },\n    // Tag-based routing: `Policies` operations use this credential regardless of\n    // HTTP method. Omit `scoped` entirely to rely on method-based routing.\n    scoped: {\n      Policies: {\n        clientId: process.env.PALISADE_POLICY_CLIENT_ID ?? '',\n        clientSecret: process.env.PALISADE_POLICY_CLIENT_SECRET ?? '',\n      },\n    },\n  },\n  primary: {\n    vaultId: process.env.PALISADE_VAULT_ID ?? '',\n    walletId: process.env.PALISADE_WALLET_ID ?? '',\n  },\n})\n\n// GET with a query param → routed to the wallet-read credential. `wallets` is\n// typed as `vaultv2Wallet[] | undefined` straight off the schema.\nconst listed = await palisade.api.call('VaultService_ListGlobalWallets', {\n  query: { pageSize: 50 },\n})\nconsole.log('wallets in org:', listed.wallets?.length ?? 0)\n\n// GET with path + query params. Placeholders in `/v2/vaults/{vaultId}/…` are\n// filled from `path`; a missing one throws before any request is sent.\nconst balances = await palisade.api.call('BalanceService_GetWalletBalances', {\n  path: {\n    vaultId: process.env.PALISADE_VAULT_ID ?? '',\n    walletId: process.env.PALISADE_WALLET_ID ?? '',\n  },\n  query: { currencyCode: 'USD' },\n})\nconsole.log('aggregated fiat value:', balances.aggregatedFiatValue)\n\n// POST → routed to the transactions credential. The body is type-checked\n// against the operation's request schema (`name` and `details` are required).\nconst counterparty = await palisade.api.call(\n  'CounterpartyService_CreateCounterparty',\n  {\n    body: {\n      name: 'Acme Capital',\n      details: { type: 'ORGANIZATION' },\n    },\n  },\n)\nconsole.log('created counterparty:', counterparty)\n\n// A `Policies` operation → routed to the scoped credential registered above\n// (not the wallet-read client its GET method would otherwise select).\nconst limits = await palisade.api.call('PolicyService_ListGlobalWalletLimits')\nconsole.log('global wallet limits:', limits.walletLimits?.length ?? 0)\n","lang":"ts"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"see-also","__idx":1},"children":["See Also"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"/docs/simplexrpl/references/connectors/palisade"},"children":["Palisade connector"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"/docs/simplexrpl/references/connectors/connector-routing"},"children":["Connector Routing"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"/docs/simplexrpl/references/verticals"},"children":["Verticals"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/ripple/simpleXRPL/blob/main/docs/palisade-api-coverage.md"},"children":["Palisade API — simpleXRPL coverage"]}]}]}]},"headings":[{"value":"Call Palisade Operations Directly","id":"call-palisade-operations-directly","depth":1},{"value":"See Also","id":"see-also","depth":2}],"frontmatter":{"seo":{"description":"Call the Palisade API directly for any operations simpleXRPL verticals don't expose.","title":"Call Palisade Operations Directly"},"labels":["simpleXRPL","SDK"]},"editPage":{"to":"https://github.com/ripple/opensource.ripple.com/tree/main/docs/simpleXRPL/tutorials/call-palisade-operations-directly.md"},"lastModified":"2026-08-21T20:52:47.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/simplexrpl/tutorials/call-palisade-operations-directly","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}