VRPlatformVRPlatform
Build a Product UI

Access and Permissions

Assign dashboard roles, partner reach, and API-key capabilities

Last Updated: 2026-09-03

Version: 1.1

VRPlatform uses the same primitive permission vocabulary for interactive users and API keys, but their bundles are separate grants.

GrantStored onPurpose
Dashboard role (ui:*)Team membershipControls a signed-in user's product access
Partner API bundle (partner:*)Partner API keyControls a backend integration
Managed-team reachPartner membershipControls which managed teams a user can open
Partner deny policyManaged teamRemoves selected partner-derived permissions

Assigning a dashboard role never changes an API key. Granting an API-key bundle never changes a user membership.

Dashboard Roles

Dashboard roles are versioned ui:* bundles. The API expands the selected membership's bundles and returns the effective union as GET /me.membership.permissions.

Broad Team Access

UI choiceIncludesDoes not include
Team AdminStandard Member, audit, access admin, and bank setupACH execution
Standard MemberProduct, settings, GL, and bankingAudit, access, bank setup, ACH execution

Focused Team Access

Use this matrix for Operations and Read Only. View means read access. Other verbs name the additional actions granted in that area. A dash means the role does not grant that workflow.

WorkflowRead OnlyOperations
Team settingsViewBasic team view
Member rosterView
Integrations and webhooksView
CalendarViewView
FilesViewView and upload
Listings and contactsView and exportView
OwnershipsViewView
ReservationsView and exportView
TransactionsView and exportView all; create and edit expenses
General ledgerView
AccountsView and exportView
Tax and mappingsView
Owner statementsView and exportView, edit, publish, and export
Statement layoutsViewView
Recurring fees and commissionsViewView
Reports and metricsView and export
Bank accounts and rulesView
Bank recordsView and export

Read Only includes team discovery so connection details and every listed settings view can resolve the selected team before loading its domain data.

GET /booking-channels supports both Integrations and Recurring Fees. It accepts either integrations:read or recurring-fees:read, so focused roles and API keys can resolve fee channel data without receiving integration access.

Transaction writes use one independent permission for each public type: transactions:expenses:write, transactions:deposits:write, transactions:transfers:write, and transactions:payouts:write. Operations receives only the expense permission. A type change requires both type permissions, and a mixed batch is rejected before any item is written when a required type permission is absent. Expense payment state still requires the separate payment permission supplied by ACH Payer.

Additive Privileges

These privileges are independent of team access. They add a sensitive or partner-specific capability and are not substitutes for a team-access role.

PrivilegeAddsDoes not add
Audit LogSelected-team public activity historyOther product access
Partner AdminPartner administration and integrationsTeam reach or ACH
ACH PayerRecord payments and execute ACHBank setup or administration

Partner Admin is available only to partner-team members. It covers partner members, managed teams, sessions, integrations, webhooks, audit, and API keys. ACH Payer is available on every team.

Global VRPlatform administrators cannot save owner or vendor bank details or execute, cancel, or recover ACH payments. Use a direct customer-team membership with Team Admin and ACH Payer when testing those workflows.

A managed team's deny policy can remove ACH execution from partner-derived access even when the partner member has ACH Payer. Direct memberships do not consume that policy.

Stable Bundle Names

UI labelAPI catalog titleBundle name
Team AdminTeam Adminui:team-admin:v1
Standard MemberStandard Memberui:standard-member:v1
OperationsOperationsui:operations:v1
Read OnlyRead Onlyui:read-only:v1
Read activity historyAudit Logui:audit:v1
Manage partner organizationPartner Adminui:partner-admin:v1
Execute ACH paymentsACH Payerui:ach-payer:v1

For exact primitive permission strings, use GET /team/permission-bundles. Each catalog entry returns its complete permissions array. The tables above group those strings into UI workflows.

Every current dashboard bundle includes operations:read. There are no account-specific role assignments in V1.

Build a Role Picker

The API accepts multiple bundles and combines their permissions. The role picker should present exactly one team-access role: Team Admin, Standard Member, Operations, or Read Only. Do not expose the bundle array as an undifferentiated multi-select.

Then render the independent controls:

ControlAvailabilityEffect
Read activity historyEvery teamAdd Audit Log
Manage partner organizationPartner-team members onlyAdd Partner Admin
Execute ACH paymentsEvery teamAdd ACH Payer
Managed-team accessPartner-team members onlySelect all or assigned teams

A partner-team member therefore receives Team access, Partner organization, Sensitive permissions, and Managed-team access sections. A non-partner member receives only Team access and Sensitive permissions.

Partner Admin is independent because it governs the parent partner organization; Team Admin governs the selected team's product and administrative access. ACH Payer remains independent because even Team Admin and Standard Member exclude money movement.

This hierarchy is product guidance. Until the API enforces it, clients must still handle existing members with any valid bundle array.

Gate navigation and actions using membership.permissions, never a primary role, bundle name, or legacy admin/user label. A member with no bundles can still load GET /me and GET /me/teams, but receives no product permissions.

Role Endpoints

TaskEndpoint
Load assignable roles and expanded permissionsGET /team/permission-bundles
Load primitive permission namesGET /team/permissions
Replace a member's complete assignmentPUT /team/members/{userId}/permission-bundles
Load the selected user's assignment and effective permissionsGET /me

Team Admins may replace their own assignment, including adding or removing ACH Payer. Removing their own Team Admin access is allowed only when another active direct access manager remains. The same final-manager rule applies to updates of other members.

Invitations and Compatibility Updates

ActionBundle behavior
Invite in permission modeSend permissionBundles, including [] when intentional
Resend or copy an invitationOmit permissionBundles to preserve the complete assignment
Submit the same legacy rolePreserve the complete bundle assignment
Change a legacy roleReplace bundles with that role's compatibility default

New and legacy non-admin user memberships default to Standard Member. Existing team admins map to Team Admin, and existing partner-team admins also map to Partner Admin. Before permission mode is enabled for a user, authorization continues to follow the legacy role while the API keeps bundle data populated. An invitation delivery failure does not roll back a committed role change.

Partner-Member Team Reach

A partner member's permissions and team reach are independent. Configure the role picker and managed-team picker as separate controls.

ReachTeams available through the partner membership
allEvery child team managed by the partner
assignedExplicitly assigned managed teams only
assigned with no teamsNo managed teams

Direct or owner membership on a child team remains available independently of partner assignments.

Before permission mode is enabled, users retain legacy broad partner reach. The stored all or assigned selection takes effect when permission mode is enabled, without a separate membership migration.

Resolve Access

Selected-team relationshipPermission sourceaccessSource
Direct child-team membershipChild membership's bundlesdirect
Partner all reachPartner membership's bundlespartnerDerived
Explicit partner assignmentPartner membership's bundlespartnerDerived
No applicable relationshipNo accessNot returned

A direct membership always wins over partner-derived access. Partner-derived access also applies the selected child team's partner deny policy.

Use GET /me/teams as the authoritative team-switcher source. Use GET /partner/members to render each partner member's roles, reach mode, and explicit assignments. Replace managed-team reach through PUT /partner/members/{userId}/memberships.

UpdateResult
Select assignedReplace only the partner-managed team assignments
Select assigned with teamIds: []Remove all partner-derived child-team reach
Select allClear explicit partner assignments and allow every managed team
Remove the partner memberRevoke partner-derived assignments

These changes never delete genuine direct or owner memberships.

Restrict Partner-Derived Access

A directly authorized Team Admin can manage the selected team's partner deny policy through GET and PUT /team/partner-permission-policy.

PrincipalPolicy appliesCan edit policy
Partner-derived dashboard userYesNo
Partner API key selecting the teamYes, after full team enablementNo
Embedded session for the teamYes, after full team enablementNo
Direct team memberNoTeam Admin only

The policy stores primitive permission names. A denial wins over a granted bundle. Use it to withhold sensitive actions such as ACH execution, exports, or member-role management. The policy applies team-wide rather than to one bank account or one partner user.

New teams deny ach-payments:execute to partner-derived access by default, and the same denial is backfilled onto existing teams without replacing other denials. A directly authorized access manager must explicitly remove that denial before a partner can execute ACH for the client. Direct team membership never consumes the partner deny policy.

Partner API-Key Bundles

Partner keys may omit bundles for unrestricted partner access or declare up to the supported reviewed bundles. Restricted keys must have every primitive permission required by an operation.

BundleDomainIncluded workflow
partner:accounting-data:v1AccountingCore records, mappings, tax, and fees
partner:ach-payments:v1ACHOwner payment-method submission and Ramp execution
partner:audit:v1AuditRedacted public audit events for selected and managed teams
partner:banking:v1BankingAccounts, connections, Plaid, bank records, rules, and cleanup
partner:calendar:v1CalendarRead, create, update, and remove blocks
partner:files:v1FilesRead, download, upload, update metadata, and remove files
partner:general-ledger:v1General ledgerClosing, opening balances, and imports
partner:integrations:v1IntegrationsApps, connections, flows, syncs, and imports
partner:onboarding:v1OnboardingTeam onboarding guide and issue operations
partner:payments:v1PaymentsRecord expenses and owner or manager payouts
partner:provisioning:v1ProvisioningDiscover and configure teams; issue sessions
partner:recurring-fees:v1Recurring feesFee and listing-period workflows
partner:reports:v1ReportsReport reads, metrics, and exports
partner:statement-layouts:v1LayoutsRead, create, assign, and remove layouts
partner:statements:v1StatementsManage, publish, and export statements
partner:team-deletion:v1Team deletionDelete managed teams and read operations
partner:team-members:v1MembersRead, invite, update, and remove members
partner:webhooks:v1WebhooksSubscriptions, deliveries, tests, rotation, and replay

Current early-access domain bundles include destructive operations supported by their domain. Credential management, self-service, internal, demo, and legacy routes remain unavailable to partner API keys.

Authentication expands stored bundle names using the current catalog, so a catalog update applies without replacing an existing key.

GET /api-tokens/permission-bundles returns the assignable API-token catalog. Each entry contains the stable name, display title, display description, and expanded permissions. Use this endpoint to render token bundle selectors instead of keeping a separate client-side list. It uses the same catalog shape as GET /team/permission-bundles for human roles.

Separate Recording From Money Movement

Permission or bundleEffect
partner:payments:v1Records eligible payments and payouts without ACH execution
partner:ach-payments:v1Adds ACH setup and execution capabilities
transactions:mark-paidRecords an expense payment with provider: null
statements:record-payoutRecords an owner or manager payout without dispatch
ach-payment-methods:writeSubmits an owner or vendor ACH payment method
ach-payments:executeExecutes, cancels, or unlinks a Ramp payment attempt

A restricted partner key must combine partner:payments:v1 and partner:ach-payments:v1 to move money. provider: "ramp" requires the applicable recording permission and ach-payments:execute before VRPlatform reads provider state or queues work.

Implementation Checklist

  1. Load role and primitive-permission catalogs from the API.
  2. Present one of Team Admin, Standard Member, Operations, or Read Only.
  3. Keep partner administration, ACH, and managed-team reach independent.
  4. Save complete replacement arrays, including intentional empty arrays.
  5. Re-read GET /me after the selected user's own access changes.
  6. Gate every action from effective primitive permissions.
  7. Treat the final API response as authoritative under concurrent changes.

On this page