@getpara/rest-sdk, alongside the server SDK. ParaServer signs with your wallets, while ParaRestClient with your secret API key runs the calls on this page.
Run Permissions administration from your backend with the REST SDK and your secret API key. This page covers assigning approvers, binding wallets to an authorization scope, changing adjustable approval settings, and reading policy state and history for support and audits.
Your backend cannot change policies themselves: those go through the Developer Portal or the CLI on a Development key, and reach production through a production review. Assignments, wallet bindings and approval settings belong to the environment you write them in, so set them up again with your production secret key after the policy is published there.
Connect
Create oneParaRestClient with your secret API key and keep it on the server.
env defaults to "PROD", so set "BETA" while you test. Every Permissions method accepts an optional last argument, { idempotencyKey, signal }.
Conditional approvals and personal limits are turned on for each app by Para. Until they are, the calls on this page that use them return
403 with PERMISSIONS_V2_EXTENSION_UNAVAILABLE.Assign roles and attributes
An authorization scope is an ID you choose that groups approvers, wallets and approval settings, such as one scope per customer organization. Assignments give a Para user roles and attributes in a scope, and the policy’s eligibility rules decide what those assignments allow.- The call replaces the user’s whole set. To change it later, read it with
getUserApprovalAssignments(scopeId, userId)and send the set you want with itsrevision. Sendassignments: []to remove them all. - Use
expectedRevision: 0for a user’s first set. A stale revision returns409withauthority assignments changed; read the current revision and retry. - Each name must be declared by an active policy, so activate the policy first.
- A user can hold at most 25 assignments across all scopes in your app. More returns
400witha user may have at most 25 assignments in one partner project, so plan for this if one person approves for many scopes. - The user must have a wallet connected to your app. Assigning roles to anyone else returns
400withuser is not linked to this app. Removing a user’s assignments works either way.
listAuthorizationScopeMembers(scopeId, { limit, afterUserId }) lists the users who hold assignments in a scope.
Bind wallets to the scope
A wallet’s binding tells Para which scope supplies its approvers and settings. A wallet that matches an approval rule without a binding is refused with403.
getWalletAuthorizationScope(walletId), and pass its revision to move the wallet to another scope. The wallet must belong to your app; a wallet from another app returns 403.
Moving a wallet to another scope invalidates its open approval cases with authorization_scope_changed, so Para asks you to confirm the move first, as described below.
Configure adjustable approval settings
When a requirement declares adjustable approval settings, your backend can change them for a scope without a new policy version. Find the requirements, then read and update one:resetApprovalConfiguration(reference, { expectedRevision }) returns the requirement to its published values. Saving or resetting invalidates open cases for the requirement in that scope. The adjustable parameters page covers the setting kinds and their rules.
Confirm changes that affect open approvals
replaceUserApprovalAssignments, setWalletAuthorizationScope, updateApprovalConfiguration and resetApprovalConfiguration check for open approval cases before they write.
An approval case is open while it is
pending, and after it completes until it is used to sign or expires. Para refuses a change that would invalidate open cases until you confirm it. A confirmed change ends those cases as invalidated, and their requests need a new attempt.Through the API, a refused change returns 409 with code APPROVAL_CASES_AFFECTED and the case IDs in affectedCaseIds, and nothing changes. To confirm it, send the same change again with force: true.In the REST SDK, the error is a ParaRestError with that code, and ParaRestError.affectedCaseIds lists the cases.getPartnerApprovalCase to tell the people waiting on them.
Cancel a pending case
Your backend can withdraw any pending case in your app, for example when the payment it covers is no longer needed:pending case can be cancelled. The case ends with status cancelled and terminalReason case_cancelled. When a pending transaction from a user’s wallet is waiting on the case, Para discards it, so that request never signs. A request that should still go ahead needs a new attempt, which opens a new case.
Cancelling a case that is no longer pending returns 409 with conditional approval case is not pending. A signing call that is still waiting on the discarded transaction throws TransactionReviewDenied.
Read state without acting for the user
Your backend can read what users and approvers have done, but it cannot act for them. It cannot grant consent, change a user’s personal limits, or approve or reject a case.
User reads need the user to have a wallet connected to your app; otherwise they return
403 with user has no wallet connection to the authenticated partner. Case reads return the same fields approvers see, except decision.
getPartnerPolicyUsage needs chainId: a decimal chain ID for EVM, or the network form for other wallet types, such as solana:mainnet. Meters for Safe spending limits appear only when you also pass the Safe’s address as safeAddress. The result is a snapshot of committed and reserved spending, not a preview of a future request.