Team Setup
Discover, create, and initialize a team for an integration
Use a partner API key for the partner-scoped routes on this page. Partner API
keys are issued by VRPlatform during partner onboarding — see
Authentication and Credentials. Collection routes
like list teams are partner-scoped and take no
x-team-id header. Singleton team routes use x-team-id.
Discover Teams
curl 'https://api.vrplatform.app/teams' \
-H 'x-api-key: <partner-api-key>'Store the returned team ID. Use it for team-scoped product requests and embedded sessions.
Each listed team includes isBillable, a non-nullable effective
billingPartnerId, and matching billingPartner metadata. The effective
billing partner is the explicit billing partner when present, otherwise the
managing partner, otherwise VRPlatform. The billingPartnerId query filter
uses that same effective relation.
status is the derived lifecycle state. It is active only when both the
team and its effective billing partner have active calculated subscription
state. There is no separate administrative status in team responses. The
status query parameter uses the same calculation, so a returned
row always matches the requested status.
Team rows returned by GET /partner/billing use the same status and
capability contract.
Before presenting an activation action, inspect capabilities.activate. It
contains enabled and typed disabledReasons. Disable activation when it is
not enabled and show the corresponding reason. Deactivation remains available.
PUT /team rechecks the same condition and returns 400 BAD_REQUEST with the
requested and current status plus the disabled reasons in structured context
if state changed after the read.
Add includeAggregates=true for partner-dashboard summaries:
curl 'https://api.vrplatform.app/teams?includeAggregates=true' \
-H 'x-api-key: <partner-api-key>'That opt-in adds active-listing, non-owner member, active-connection,
current connection-issue, and direct child-team counts. Omitting the parameter
omits aggregates entirely and keeps the default request lightweight. Partner
listing totals include the partner's direct listings and listings belonging to
clients billed through that partner.
The singleton get team response always includes
isBillable and aggregates; it does not require includeAggregates.
Team resolution uses the control plane for identity, placement,
billingPartnerId, and billingPlan. Hyperline customer identity,
subscription, payment-method, trial, cancellation, and accounting state remain
regional. If you need billingCustomerId, call GET /team at the
apiBaseUrl returned by GET /teams/resolve; the resolve response does not
include this regional field.
Team administration views can filter with billingPartnerId,
isOnboarding, billingSubscriptionStatus, billingPlan, product, and
comma-separated featureIds. Subscription filters support missing,
viaPartner, and pendingCancellation; plan filters support other and
none; product accepts vrtrust or vrintegrations. Filters are applied
before pagination, so pagination.total describes the complete filtered
regional result. Request each portfolio region separately with x-data-region.
Read Monthly Partner Billing
Use list partner billing to load the property-manager teams billed by the authenticated partner for one month:
curl 'https://api.vrplatform.app/partner/billing?month=2026-06' \
-H 'x-api-key: <partner-api-key>' \
-H 'x-data-region: us'For a completed month, each team uses its latest retained
listings_reported count explicitly attributed to the authenticated partner
through the legacy date-only month-end cutoff. Attribution is filtered before
the latest event is selected. A currently billed team without an attributed
event uses its live count only when another listing report exists in that
historical window; teams without any report in the window are excluded. The
current month always uses live counts. Live non-GL counts use calculated
listing status, including manual and PMS status, while live GL counts use
current ownership-period deactivation.
Deleted teams remain as historical rows. They keep the original team ID and
monthly listing count, use status: deleted, and return unavailable live-team
fields as null. Consumers must disable actions that require a live team.
The endpoint supports team/company search, lifecycle, accounting partner,
product, and billing-plan filters plus deterministic sorting and standard
pagination. Sort by name, created, partnerName, product,
activeListings, or billingPlan; prefix the value with - for descending
order. The default is sort=-created. Filtering happens before totals and
page selection. One request reads one regional partition; request each
portfolio region separately and retain region identity when combining results
or exporting CSV.
Export Active Listings
Use list partner listings to export active property-manager listings for the current partner or VRP-admin dashboard:
curl 'https://api.vrplatform.app/partner/listings?partnerId=<partner-id>' \
-H 'x-api-key: <partner-api-key>' \
-H 'x-data-region: us'The endpoint accepts the dashboard's team IDs, team/company search, lifecycle,
onboarding, accounting-partner, effective billing-partner, subscription,
billing-plan, product, and enabled-feature filters. Filters run before
pagination.total and page selection. Only listings that pass the same live
active-listing calculation as partner billing are returned: non-GL listings
use calculated listing status, while GL listings use ownership-period
deactivation.
Each row contains the listing ID and calculated display name, owning team ID
and name, structured address fields, and the full stored address. Rows are
ordered by team name and calculated listing name with stable ID tie-breakers,
so clients can combine every page directly into the existing Listings CSV.
Request each advertised portfolio region separately. When explicit team IDs
are supplied, any ID outside the authorized selected region returns 403
instead of producing an incomplete export.
Create A Team
curl 'https://api.vrplatform.app/teams' \
-X POST \
-H 'x-api-key: <partner-api-key>' \
-H 'content-type: application/json' \
--data '{
"name": "Example Team",
"email": "team@example.com",
"generalLedger": false
}'The generated operation defines all optional billing, address, portal, and
member fields. generalLedger: false creates the team without accounting
setup. When generalLedger is omitted, true, or a configuration object, the
API runs team initialization as part of the create request: it provisions the
chart of accounts, tax rates, statement layouts, recurring fees, and line
mappings from the default template (or from copyFromTeamId in the
configuration object). Create team does not support
dry run.
When defaultCurrency is provided, it must be present in the target region's
supported currency catalog. An unsupported value returns 400 BAD_REQUEST
with context.defaultCurrency, and no team is created.
In the Hostaway data region, omitting copyFromTeamId selects the approved
Hostaway default. Its 54 concrete line mappings include a non-posting
processing-fee reference account and a posting VAT-collected revenue account.
Discounts map to rents and retain their negative source amounts.
guestChannelFee and airbnbTransientOccupancyTax are excluded. Standard tax
types are excluded only for the exact Airbnb booking channel, while
airbnbPassThroughTax remains posted. hostChannelFee uses the general
channel-commission reference account except for its Airbnb expense-account
override. Custom Hostaway fee names are mapped after their concrete type is
known.
When provisioning with a partner API key, uniqueRef is required: send your
own stable identifier for the customer. Exactly repeating a completed create
fails with 409; the error's context.existingTeamId identifies the existing
team. A changed payload for the same key fails without a resumable id. Load the
existing team with lookup team instead of
re-posting. Retrying a create request that failed before completing is safe; a
request that succeeded must not be repeated.
New teams are placed in the data region of the API host you call, so omit
dataRegion unless you deliberately target another region from a multi-region
host. A region that has no provisioned cell is rejected with 400.
Duplicate A Team
Use POST /team/duplicate to create an asynchronous test-team copy of a
partner-managed property-manager team. Select the source with x-team-id and
send a partner API key that has the partner:provisioning:v1 bundle. A
restricted key also needs partner:audit:v1 to poll completion.
curl 'https://api.vrplatform.app/team/duplicate' \
-X POST \
-H 'x-api-key: <partner-api-key>' \
-H 'x-team-id: <source-team-id>' \
-H 'content-type: application/json' \
--data '{
"name": "Blue Crush Demo",
"uniqueRef": "blue-crush-demo-001",
"anonymize": true
}'The response identifies the deterministic target and the audit action:
{
"actionId": "c8e5e122-e568-4b10-959e-ca88aa6778ce",
"anonymized": true,
"name": "Blue Crush Demo",
"sourceTeamId": "277698df-a242-4f8d-b2f7-af69b79d85be",
"status": "queued",
"targetTeamId": "b8c49c19-3528-5c10-8b67-f3b72ad525df",
"uniqueRef": "blue-crush-demo-001"
}anonymize defaults to false. When enabled, the worker deterministically
replaces visible guest, owner, listing, contact, address, bank-display, and
free-text data while preserving amounts, dates, and relationships.
The target is always a test team assigned to the same partner. The supported business and accounting graph includes listings, ownership periods, reservations, payments, transactions, bank records, journals, statement layouts, recurring fees, and owner statements. Users, tokens, audit history, files, webhooks, automations, tasks, live credentials, and sync runtime state are not copied. Connections are copied only as disabled shells with empty credentials and persistent state.
Treat uniqueRef as the idempotency key. An exact retry returns the same
targetTeamId and safely resumes the audit work. Changing the name or
anonymize value for that key returns 409; use a new uniqueRef for a
different clone. A key already used by another team for the partner also
returns 409.
Poll GET /audit/actions/{actionId} with the source x-team-id. The initial
response means the work was queued; use the action's effect counts to decide
when the duplicate is complete or failed. Polling requires audit:read, which
is included in partner:audit:v1.
Completion includes the target's control-plane identity and connection routes. If the background runtime cannot access separate regional and control-plane databases, the effect fails instead of returning a regional-only duplicate.
Initialize Later
Use initialize team only when the selected team
still needs GL initialization or a specific copy/include plan. Send the
selected team in x-team-id. The operation supports dry run.
Initialization can copy selected accounts, tax rates, mappings, fees, or statement layouts. Treat it as an accounting setup operation, not a repeated idempotent bootstrap call.
Manage the Onboarding Guide
Use GET /team/guides/onboarding to read the selected team's VRPilot onboarding
checklist. Every response contains the fixed step set with status and the
server-owned updatedAt timestamp.
Use PUT /team/guides/onboarding with exactly one guide or step key. A step can
be set to completed, skipped, or null. These are manual checklist choices:
the API does not require the step's normal product action to exist before it
accepts completed. Sending null records an explicit incomplete choice, so a
live completion signal does not immediately complete that step again.
PUT /team/guides/onboarding
Content-Type: application/json
{
"openingBalances": "completed"
}Automatic completion still applies to untouched steps when the related setup is detected. Reopening a required step also reopens a completed guide. Optional steps can be reopened without changing the guide-level completion status.
Guide-level status: completed remains valid only after every required step is
either completed or skipped. This is the overall checklist gate; it does not
prevent manual status changes on individual steps.
Verify
Load the selected team and inspect ID, status, type, GL state, books-closing date, partner relationship, and available connection capabilities. Then continue to Connections.
Update Team Branding
Use update team with the selected team in x-team-id to
set logo or colorPrimary. Both fields support explicit clearing: send
null to remove the stored logo or primary color. Omitting either field leaves
its current value unchanged.
List Managed-Team Users
Use list partner users to build a user directory across managed child teams. The collection excludes anyone who has a direct membership on the partner team itself, even when that person also has a managed child-team membership. Search, user views, team filters, totals, and pagination all operate after this exclusion.
When the portfolio spans regions, request each region advertised by GET /me
with x-data-region; one response contains only the selected regional
partition.
List Partner-Team Members
Use list partner members to build the
partner team's own member directory. Each root row includes the member's
role, status, and lastInvitedAt from the partner-team membership. Its
memberships array contains only managed child-team memberships.
Invite A Team Member
Use invite team member with the
selected team in x-team-id. Set sendEmail: false to create a copyable link
instead of sending the email immediately. The endpoint does not support dry
run because it creates an invite token and dispatches notification work.
An email already used by an owner account cannot also be invited as a team
member. That request returns 400 BAD_REQUEST; use the structured error code
for behavior and display its message to explain the conflict.
If the email provider has suppressed the address after a bounce, complaint, or
manual suppression, the request also returns 400 BAD_REQUEST. Offer
sendEmail: false to create a copyable invite link, or ask for another email
address. The response uses a static message and does not expose provider or
recipient diagnostics.
Delete A Team
DELETE /team?confirm=true queues deletion of the team selected by
x-team-id. This administrative operation requires an authenticated active
VRPlatform member. Partner API keys, service tokens, and ordinary tenant users
receive 403 and must contact VRPlatform support. force=true bypasses active
resource checks, but it does not bypass the active-subscription guard.
Deletion runs asynchronously after validation. A successful response confirms that the deletion task was queued, not that every cleanup step has completed.
API Reference
- List teams —
GET /teams - List monthly partner billing —
GET /partner/billing - List active partner listings —
GET /partner/listings - Create team —
POST /teams - Duplicate selected team —
POST /team/duplicate - Get selected team —
GET /team - Update selected team —
PUT /team - List managed-team users —
GET /partner/users - List partner-team members —
GET /partner/members - Invite team member —
POST /team/members/invite - Initialize team —
POST /team/init - Delete selected team —
DELETE /team
