VRPlatformVRPlatform
Integrate & Migrate Data

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.

Creation writes isOnboarding: false when the field is omitted. Send true to start onboarding, or false to create a team outside onboarding. Creation and update requests reject explicit null. An update that omits the field keeps the team's current value.

For a new team outside onboarding, successful subscription creation continues through the normal activation workflow when the team is active and has no scheduled cancellation. Billing partner, payment and subscription ownership checks still apply. This can start billing under the team's existing contract. Existing pending subscriptions require a separate activation.

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.

Test and demo classification

Team detail, list and resolution responses include the required, read-only isTest boolean. It is also available in GET /partner/teams, GET /me/teams, the selected GET /me team, GET /partner/billing rows and internal billing team rows.

isTest applies the same direct rule to the team, its accounting partner and its billing partner. The direct rule is true for a designated system/test team or a team whose own partnerId or billingPartnerId points to Demo and Test Console. Any of these three checks makes isTest true. A parent's inherited classification does not propagate further.

The accounting partner is checked even when a separate billing partner is selected. When no explicit billing partner is selected, the effective billing partner is the accounting partner, otherwise VRPlatform.

Parents can belong to another region. Changing only a parent's own references updates the child's computed classification on subsequent reads; the child does not need to be edited. The stored regional test flag does not control this field, and clients cannot set it.

excludeTestTeams=true, internal billing filters and accounting monitoring currently apply the direct rule before pagination and totals. Their inherited classification is being aligned with the response field. Until that rollout is complete, a child classified only through a parent can still appear in a filtered list. Legacy stored flags are ignored.

Consumers use this field for sandbox billing, production reporting and CRM exclusions. Consumers that still calculate classification from direct team references require a separate migration to inherit the API classification.

Billing and lifecycle

VRPlatform assigns the billing plan during subscription provisioning. Changes to the effective billing partner reconcile that plan through the regular lifecycle; teams outside onboarding can activate after current listing usage is synchronized. isOnboarding is a required boolean in team responses. true waits for completion; false means onboarding is not in progress, including teams that never enter it. Creation defaults an omitted field to false and requests normal subscription activation after the binding is saved. Create and update requests reject explicit null.

Each listed team includes 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. A team must have stored active status and an active or unset subscription state. A pending subscription also allows active status while isOnboarding is true. The same rule applies to a regional billing partner; an inactive effective billing partner keeps its teams inactive. Errored subscriptions remain inactive, including during onboarding. Active listings can be counted for usage preparation while onboarding. This does not activate the subscription. New teams outside onboarding enter activation after subscription creation; teams in onboarding enter it when onboarding completes. 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. Pending onboarding teams can be active while capabilities.activate remains disabled. Completing onboarding still uses the normal subscription activation workflow. Billing lists retain their separate status=onboarding filter. Billing and connection responses expose boolean onboarding.

A billing partner can be homed in a different data region from its teams. Its global record decides its status there, so its teams keep their status and active-listing counts in every region.

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.

Property-manager and partner teams billed directly by VRPlatform or Demo and Test Console need a saved billing customer, a saved subscription, and active billing before activation is enabled. Missing billing returns teamBillingSubscriptionInactive, including when the subscription status is unset. System and admin teams retain their existing activation rules.

Status changes through PUT /team have two more restrictions:

  • A team explicitly billed by VRPlatform or Demo and Test Console cannot change status. The request returns 400 BAD_REQUEST.
  • Without VRPlatform-admin authentication, the caller must be a user with an active non-owner membership on the team or its managing partner, or an active VRPlatform membership. Other callers receive 403 FORBIDDEN.

PUT /team rejects type: "admin" with 400 BAD_REQUEST.

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, total-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.

aggregates.totalListings includes inactive listings. aggregates.activeListings uses the existing active-listing rules. Both counts retain the existing partner attribution. An empty portfolio returns zero for both counts.

The singleton get team response always includes aggregates; it does not require includeAggregates.

Team resolution uses the control plane for identity, placement, billingPartnerId, and billingPlan. Hyperline customer identity, subscription, payment-method, cancellation, and accounting state remain regional. If you need billingCustomerId or billingSubscriptionId, call GET /team at the apiBaseUrl returned by GET /teams/resolve; the resolve response does not include these regional fields.

When only the billing customer ID is known, use GET /teams?billingCustomerId=cus_example with x-data-region to find its current bindings. The exact-match filter applies before pagination and only returns teams the caller can access. Query each relevant region for a portfolio-wide lookup.

billingSubscriptionId is a nullable regional reference. Normal subscription creation binds one current subscription only after validating its customer and billing environment. An existing binding is preserved. Customer or environment ownership resets clear it; clones and separate VRI-to-VRT teams start unbound, while region moves preserve it. An effective cancellation can clear the subscription reference while retaining the customer. Changing the customer requires the same update to assign or explicitly clear the subscription. Daily monitoring reports missing, invalid, and inconsistent bindings without changing them. Billing lifecycle tasks, billing details, monitoring and MRR use this exact subscription. When the reference is absent, consumers do not select another subscription from the customer. Creation persists the binding before activation reloads it. A pre-creation snapshot can still be unbound at that point. Events for other subscriptions do not update team billing state.

An ordinary team update also provisions missing direct billing when the payer stays the same. The team must have stored active status, be outside onboarding, and have no cancellation date. Cancelled or errored billing is excluded. Delayed updates recheck the current binding, payer, environment, onboarding, suspension, and cancellation before provisioning. Provisioning saves the subscription and reconciles its plan without requesting paid activation. Repeating the update after the binding is saved does not create another subscription.

A scheduled cancellation keeps the subscription binding and current team status through its effective date. The effective cancellation records the cancelled state and date, clears the binding, and deactivates the team. An active subscription event does not reactivate a team that was made inactive independently. A new subscription is bound only through an explicit creation or eligible initial-assignment flow.

Internal billing callers can submit customer/subscription IDs together with the current plan and billing status in one request. The API validates the assignment before applying those fields. Repeating the same assignment still applies supplied state changes; a conflicting assignment fails before changing billing state. Sending only IDs leaves the existing plan, status, and access unchanged.

When PUT /team completes onboarding, it does not initialize or change subscription status, billing plan, or cancellation date. Missing billing state remains visible until the Hyperline workflow reconciles it.

Test and demo teams use Hyperline Development. Production teams use Hyperline Production regardless of the partner's identity. Billing setup resolves the payer through the effective billing partner relationship. Changes within the same environment retain the customer; moves between environments clean up the source before creating the target binding. Partner clients own their subscription, while their billing partner pays consolidated invoices. They do not need their own payment method.

When a billing-partner change creates a team's first subscription outside onboarding, the billing effect also requests activation. A missing previous subscription ID does not suppress activation. An explicit true to false update leaves onboarding. Administrative suspensions, scheduled cancellations, teams still onboarding, and creation skipped by the pricing rollout do not enter this first-subscription activation path.

Team administration views can filter with billingPartnerId, isOnboarding, billingSubscriptionStatus, billingPlan, product, and comma-separated featureIds. isOnboarding=true selects in-progress onboarding; false selects teams outside onboarding, including teams that never enter it. The same onboarding filters apply to partner listing exports. Subscription filters support missing and pendingCancellation alongside actual subscription states. Billing plan filters match the exact plan name; none selects teams without an assigned plan, such as newly created teams whose billing setup is pending. 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 durable billing listing fact strictly before the first instant of the following month. A prior fact carries forward when no listing changed during the selected month, so completed-month billing does not depend on analytics delivery or retention. 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.

Completed-month reads return SERVICE_UNAVAILABLE until the regional fact dataset has passed import, baseline, reconciliation, and retained-month parity checks. The same response applies to a month before the recorded imported range. An incomplete regional rollout therefore cannot become a zero-row billing response. Reconciliation records only current state at the time it runs; it never backdates live tenant, partner, listing, or ownership state into a completed month.

Each row returns isTest. Active listings count only while the team is active, so an inactive team returns activeListings: 0 for the current month.

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. Their isTest evaluates only the team ID and the billing partner. Consumers must disable actions that require a live team. Each live team row also returns the partner-provided uniqueRef. Deleted historical teams return null because their live team record no longer exists.

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. The top-level uniqueRef is the owning team's partner-provided stable identifier. 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.

Choose an Operating Country

The signup and team-creation UIs can choose placement before a team exists by calling the public country list:

curl 'https://api.vrplatform.app/countries'

The response is sorted by English country name. Each item contains its two-letter country code, full name, lowercase ISO 4217 currencies, and the dataRegion to use for team provisioning:

{
  "data": [
    {
      "code": "CA",
      "name": "Canada",
      "currencies": ["cad"],
      "dataRegion": "us"
    }
  ]
}

Use get country when only one country is needed. The path accepts a two-letter code case-insensitively, such as GET /countries/ca, and returns the country object directly. An unknown code returns 404.

Country placement follows this fixed policy:

Country continentdataRegion
North America or South Americaus
Europe, Africa, or Antarcticaeu
Asia or Oceaniaap

Pass the returned dataRegion when provisioning through the generic gateway. When a country has more than one currency, the API returns every applicable code; the client must keep or ask for the intended team default instead of silently discarding the additional choices.

Create A Team

In the portal, Sign Up opens a role menu. Property Manager continues to the registration form. Listing Owner shows instructions to use the invitation link sent by the property manager. Accounting Partner opens the Accounting Partners page to learn about the program and book a call. Partners join through an invitation from VRPlatform.

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. The API stores team email and supportEmail in lowercase on create and update, so Team@Example.com is returned as team@example.com. 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, and recurring fees. By default, a new General Ledger team bootstraps from the published Control Plane template, whether generalLedger omits copyFromTeamId or sets it to the VRPlatform team. Every part in include comes from the template, and POST /teams fails before creating the team when none is published.

The bootstrap resolves the current published template for the managing partner, or the VRPlatform global template when that partner has no template. An existing but unpublished partner template fails setup instead of inheriting global data. Every region reads the same immutable version, while the new team still receives normal regional rows with newly generated IDs. Account-linked fees, rates, and layouts are rebound through portable logical keys. Posting accounts owned by recurring fees are recreated with the fee instead of being copied as reusable ledger accounts. Preview does not create a partner default set; invalid source components return 422 UNPROCESSABLE_CONTENT with paths that must be corrected before publication. A published snapshot includes only the source team's current default statement layout. Historical non-default layouts do not block publication or become defaults for new teams. Create team does not support dry run.

Every new team starts with active Finalytic and CSV Import connections. Members listed in the request receive active memberships. The managing partner must exist; an unknown partner returns 404 NOT_FOUND. A partner whose billing plan covers only General Ledger teams cannot create a non-GL client team; the request returns 400 BAD_REQUEST.

Team creation does not assign a billing rollout feature. General Ledger teams retain their General Ledger and Operations Accounting feature assignments.

Billing-eligible partner and property-manager teams receive their own subscription through team creation, including while isOnboarding is true. Direct-billed teams may return an optimistic active status while setup completes. Partner-client subscription state comes from billing setup and follows the same rules for every partner. The billing partner remains the payer for consolidated invoices.

An explicit copyFromTeamId must belong to the target data region. A source in another region returns 400 BAD_REQUEST with the source and target regions in structured error context, and no team is created. When no template is published for the partner or the VRPlatform global scope, creation fails before the team exists.

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.

The data region does not select a different central ledger template. The published snapshot includes reservation line mappings. They are not applied at team creation unless generalLedger.pmsAppId names a PMS app and include contains lineMappings. When a PMS connects, the connection applies the mappings of the PMS app from the latest published version, matching each default account to an active account of the team: first by unique reference, then by shared assignment, then by title (account classification must be compatible for every step after the unique reference), and finally by the same category plus a shared recurring fee title. Inactive accounts are never matched. If any row of a line type (base or booking channel) has no matching account, the whole line type stays unmapped for the team to resolve. Only line types the team has no mapping or exclusion for are added.

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 from Partner teams with that ID instead of re-posting. Retrying a create request that failed before completing is safe; a request that succeeded must not be repeated. A team is not returned by partner discovery until its global identity, regional data, and requested initialization have completed provisioning. Requests addressed to a team that is still provisioning fail with 409; retry after provisioning completes.

A team created in the app, for example by a customer who signs up and connects their PMS, has no uniqueRef. When such a team connects Hostaway, it takes the Hostaway connection's uniqueRef, the Hostaway account ID, unless another team of the same partner already holds that value. A uniqueRef the team already has is never replaced. For any other team, or to change the value, use update team with the team in x-team-id:

PUT /team
Content-Type: application/json
{ "uniqueRef": "blue-crush-demo-001" }

You can change it later or send null to clear it. It must be unique among your teams; a value another of your teams uses returns 409. Changing it requires teams:provision, which partner admins, provisioning keys and platform administrators hold. The team's own members cannot change it. A POST /teams retry with the old value no longer finds the team, so finish pending creates before you change it. Changes appear in the team's audit events.

When calling the forwarding gateway, General Ledger team creation requires an explicit dataRegion of us, eu, ap, or hostaway. Omitting the region or selecting crunchy returns 400 BAD_REQUEST before the team is created. Because General Ledger is the default, the same requirement applies when generalLedger is omitted.

A propertyManager assigned to the Hostaway partner must use the hostaway data region. Any other region returns 400 BAD_REQUEST before the team is created. Operating country may still determine currency and tax defaults, but it must not determine storage placement for a Hostaway client.

When calling a strict regional API worker directly, dataRegion may be omitted and defaults to that worker's cell. An explicit region must match the cell; otherwise the worker returns 421 MISDIRECTED_REQUEST with its placement.

Non-General Ledger teams must set generalLedger to false and use crunchy. An omitted dataRegion defaults to crunchy; an explicitly selected regional cell returns 400 BAD_REQUEST before the team is created. A direct request to a regional worker with an omitted region returns 421 MISDIRECTED_REQUEST with the Crunchy placement.

Generated team slugs are checked against both the global tenant registry and the target region before the team is created. If the normalized name is already used in either store, the API selects a unique generated slug and writes it to both registries. Explicit slugs must be available in both stores.

Duplicate A Team

Use POST /team/duplicate to create an asynchronous test-team copy of a partner-managed property-manager team. The copy retains its managing partner and uses Demo and Test Console as its billing partner, so its computed isTest is true. 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. The CSV import connection is copied enabled.

Accounting references are rebound to the target graph, including account IDs embedded in recurring-fee formulas. A duplicated fee therefore calculates from the cloned team's postings rather than retaining a hidden dependency on the source team's chart of accounts.

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.

Generate Demo Data

POST /team/generate-demo-data queues a team-demo-data operation for the team selected by x-team-id and returns its operationId. Poll GET /operations/{id} for completion.

Each run adds 50 owners, 25 listings, and demo reservations and transactions under one reused API connection. The operation is not idempotent: every request creates new records, so do not repeat a request that completed.

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. A General Ledger team with no copyFromTeamId (or the VRPlatform team as copyFromTeamId) and no copyLineMappingsFromPartnerId applies the latest published template for every part in include, including a mappings-only run. Copies from any other team and partner line-mapping copies take their data from the source team. A General Ledger team copying from another team still takes its additional-fee templates and their accounts from the published template, so it also needs one. Initialization is only for General Ledger teams; other teams get 400, and connecting a PMS on them queues no line-mapping initialization.

copyLineMappingsFromPartnerId is deprecated and will be removed on 2027-02-01. It copies the line mappings of the partner's existing client teams, including changes made on those teams, and only for a PMS the team has connected. Omit it to apply the partner's published defaults. Send pmsAppId to apply them before the team connects the PMS.

Publishing a newer version does not mutate existing teams. When a team already has statements, initialization retains every layout referenced by those statements as historical and non-default. It removes unused layouts and makes the copied central layout the current default. Sending accounts for an existing General Ledger team therefore applies the latest published template to it. The VRI to VRT team migration initializes the migrated team from the published template and fails before creating the team when none is published.

A PMS connection applies the latest published line mappings for that PMS on any General Ledger team, resolved when the work runs. Default accounts are matched to the team's own active accounts; a line type with an unmatched row stays unmapped. Retries preserve existing mappings and exclusions.

To apply a PMS's line mappings before the team connects that PMS, send pmsAppId with lineMappings in include. The team needs no connection to that app. Read the result with GET /reservations/line-mappings. Any app other than a PMS returns 400. A later connection keeps these mappings and adds only missing line types.

POST /team/init
Content-Type: application/json
{
  "include": ["lineMappings"],
  "pmsAppId": "hostaway"
}

Treat initialization 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.

A user is either an owner or a team member, never both. An email already used by an owner account on any team cannot also be invited as a team member, and a team member cannot become an owner on another team. 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.

Re-inviting an existing member with the same role preserves their identity and explicit permission bundles. If that membership changes while the invitation is being prepared, the request returns 409 CONFLICT. Reload the member list before trying again.

Delete A Team

DELETE /team?confirm=true queues deletion of the team selected by x-team-id. A partner API key can delete a team only while that team is directly managed by the key's partner. Restricted keys require the partner:team-deletion:v1 bundle. Partner deletion cannot use force=true, so an active subscription, active listings, connections, automations, or journal entries inside closed books block the request. Resolve those blockers before retrying.

Sending force=true with a partner key returns 403 FORBIDDEN with a field issue explaining that force must be omitted or false. No deletion job is queued.

Omitting confirm or sending confirm=false returns 400 BAD_REQUEST with an issue pointing to confirm. No deletion job is queued.

Authenticated active VRPlatform members retain the administrative deletion path. For that path, force=true bypasses active-resource checks and statement-period locks during whole-team removal, but it does not bypass the books-closed hard lock or the active-subscription guard. Service tokens and ordinary tenant users receive 403.

A team that is still the partner or billing partner of another team, in any region, cannot be deleted, including with force=true. The request returns 400 BAD_REQUEST with details.childTenantIds, and no deletion job is queued. Move or delete those teams first. A queued deletion checks again before regional cleanup.

Deletion checks for closed-period journal entries before queuing and again before regional cleanup. A failed check leaves the team and its existing deletion data unchanged.

Scheduled cleanup excludes cancelled teams with journal entries before the first open day. A closed-books date alone does not prevent selection when no journal entry falls before that day. Direct cleanup tasks repeat this selection check before requesting deletion.

Deletion runs asynchronously after validation. A successful response confirms that the application-owned job was queued, not that every cleanup step has completed:

{
  "operationId": "00000000-0000-0000-0000-000000000000",
  "status": "queued"
}

A retry from the same requester returns the same active operation. A request from another actor while deletion is active returns 409 CONFLICT instead of transferring operation ownership.

Retain operationId and poll GET /operations/{id} for the normalized queued, running, completed, or failed lifecycle. After partner deletion, send the partner team in x-team-id when polling because the target team no longer exists. Immediate task dispatch can fail without losing the durable job; a recovery schedule starts queued work and resumes stale checkpoints. Provider run IDs, deletion steps, attempts, and failure details remain available only to internal operators. At most five team-deletion tasks execute concurrently. Each deletion locks its target team before child cleanup so background writes cannot refill the team during removal. Regional cleanup advances through committed groups, and bounded table and journal batches commit independently. A retry resumes from the last completed group instead of replaying the complete regional purge. Account rows are locked while their dependent mappings are removed. The final connection pass commits before the team row is removed. Tenant-owned connections also cascade with the team row, so a remaining connection cannot veto the confirmed deletion. Reservation mapping rows likewise cascade when their account has already passed deletion safety checks. If a legacy owner statement line from another team references a reservation owned by the deleted team, deletion preserves the statement line and clears only that reservation reference before removing reservations. The job completes only after its audit mutation and follow-up work are stored; those records can outlive the deleted team so recovery remains possible.

API Reference

Subscription recovery

Hyperline stops invoicing when a running subscription becomes errored after exhausted payment attempts. The linked subscription and pricing are preserved; GET /team.status becomes inactive through billing state. Successful native provider activation restores access while preserving independent administrative suspensions, including those on partner clients.

An eligible billing payer's administrator can request recovery with PUT /team and { "cancelation": { "effectiveAt": null } }. Send this as a standalone team change. Setup must be complete, the administrative team status active, and the linked subscription active or errored. Cancelled, voided or unbound subscriptions require reviewed operator restoration.

The request queues the existing billing task and preserves current access. Poll regional GET /team using the same team/region scope. Confirm active billing, active access and no scheduled cancellation before refreshing session data. No recovery request or invoice identifiers are required.

The provider requires an active payment method and no outstanding issued invoices. Recovery reactivates the existing errored subscription or withdraws its scheduled cancellation; it never creates a subscription or reconstructs pricing. Finite contracts, paused/pending subscriptions and in-progress migrations require review. Partner clients must contact their billing payer. Parent recovery does not remove independent child suspensions. Payment-method updates alone do not grant access; provider activation must be confirmed.

On this page