Linked Users and Linked Accounts
This guide covers two related but distinct concepts in the Spidr platform:
- Linked Users: relationships between user records (e.g. guardian/dependent, spouse)
- Linked Accounts: primary/secondary account relationships, including shared balances
Part 1: Linked Users
Overview
Users can be linked to one another to represent real-world relationships. Linkages are bidirectional: when User A is linked to User B, both user records receive a linkedUsers entry. Some linkage types are mirrored (e.g. one side is dependent, the other is guardian), while others are symmetric (e.g. both sides are spouse).
Linkage Types
Spidr supports the following linkage types:
| Type | Relationship | Behavior |
|---|---|---|
dependent | Individual → Individual | Mirrored: the other user gets guardian |
guardian | Individual → Individual | Mirrored: the other user gets dependent; guardian must be 18+ |
spouse | Individual → Individual | Symmetric: both sides get spouse |
authorized_user | Individual → Individual | Symmetric: both sides get authorized_user |
beneficial_owner | Individual → Entity | Managed via entity endpoints only, not the user PATCH endpoint |
Data Model
Each user record has an optional linkedUsers array. Each entry has the following fields:
| Field | Type | Description |
|---|---|---|
linkedUserId | ObjectId | The ID of the linked user |
linkedUserType | string | individual or entity |
linkageType | string | One of the linkage types above |
createdAt | Date | When the linkage was created |
dateArchived | Date | When the linkage was archived (undefined if active) |
API Endpoints
Individual-to-Individual Linkage
| Operation | Method | Endpoint | Key Fields |
|---|---|---|---|
| Create user with linkage | POST | /v1/user/create | primaryUserId + linkageType |
| Add or change linkage | PATCH | /v1/user/:id | linkedUserId + linkageType |
| Archive linkage | PATCH | /v1/user/:id | linkedUserId + linkageType: "archive" |
| Read user with linkages | GET | /v1/user/:id | Response includes linkedUsers |
| Read user + accounts | GET | /v1/user/:id/userAndAccounts | Response includes linkedUsers |
Entity Beneficial Owners
Beneficial owner linkage uses a separate set of endpoints:
| Operation | Method | Endpoint | Key Fields |
|---|---|---|---|
| Create entity with owners | POST | /v1/entity | entityDetails.beneficialOwners array |
| Add/edit/archive owners | PATCH | /v1/entity/:id/beneficialOwners | action: "add" | "edit" | "archive" per owner |
| Read entity with owners | GET | /v1/entity/:id | Response includes linkedUsers and entityDetails.beneficialOwners |
When a beneficial owner is added, the individual user's linkedUsers array receives a beneficial_owner entry pointing to the entity. The entity stores ownership details (ownershipPercent, prong, cipRequired) in entityDetails.beneficialOwners.
How Linkage CRUD Works
Creating a Linkage at User Creation
When POST /v1/user/create includes primaryUserId and linkageType:
- The primary user is validated (must exist, not anonymous, not an entity)
- Linkage type rules are checked (e.g. guardian age requirement)
- The primary user's
linkedUsersgets an entry pointing to the new user - The new user is built with a reciprocal
linkedUsersentry pointing back to the primary - Mirrored types are applied (e.g. if
linkageTypeisdependent, the primary getsguardian)
Adding/Changing a Linkage via Edit
When PATCH /v1/user/:id includes linkedUserId and linkageType:
- The linked user is validated (must exist, same company, not self, not entity)
- If no existing linkage exists → add: push new entries on both user records
- If an existing active linkage exists with a different type → change: archive the old linkage on both sides, then add the new linkage
- If the same linkage type already exists and is active → no change
- Separate action records and webhooks are created for both users
Archiving a Linkage
When PATCH /v1/user/:id includes linkedUserId and linkageType: "archive":
- Sets
dateArchivedon the linkage entry in both user records - The linkage remains in the
linkedUsersarray but is marked as archived
Business Rules
- Guardian age: The user designated as
guardianmust be 18 or older - Dependent age: The user designated as
dependentmust have a guardian who is 18+ - No self-linking: A user cannot be linked to themselves
- No anonymous users: Anonymous users cannot participate in linkages
- Entity restriction: Linkage changes for entity users must go through the
/v1/entity/:id/beneficialOwnersendpoint, notPATCH /v1/user/:id - Beneficial owner cap: Total ownership percentage across non-archived beneficial owners cannot exceed 100%
SST Display
Location
The "Linked Users" tab on the User show page.
Table Columns
| Column | Content |
|---|---|
| User ID | Linked user's ID with a clickable link icon to navigate to that user's Linked Users tab |
| User Name | First + Last name for individuals, Entity Name for entities |
| Link Type | Chip showing the linkage type, with a dropdown arrow to change it |
| Link Status | active (green chip) or archived (gray chip), with a dropdown to archive |
| Archive Date | Date the linkage was archived, if applicable |
Adding a Linked User
The "+" button opens a dialog with:
- Linked User ID: text input for the target user's ObjectId
- Link Type: dropdown with options:
dependent,spouse,authorized_user
Note: guardian is not available as an add option; it is automatically set on the reciprocal side when dependent is chosen. beneficial_owner is managed through entity pages.
Changing a Relationship
Clicking the dropdown arrow on the Link Type chip shows a menu listing the other three of the four individual types (dependent, guardian, spouse, authorized_user, minus the current one). The dropdown only appears on active, non-beneficial_owner rows, and only when the SST user has permission to edit the link type.
Archiving
Clicking the dropdown arrow on the Link Status chip shows a menu with a single "archive" option.
Expandable Rows
When the same linked user has multiple linkage history entries (e.g. the type was changed, which archives the old and creates a new one), the most recent linkage is shown as the primary row. Older/archived entries appear as expandable sub-rows.
Permissions
| Role | Can Add/Edit/Archive Linked Users? |
|---|---|
| Compliance | No |
| Agent | No |
| CS Manager | Yes |
The Compliance and Agent roles cannot add, change, or archive linkages. The CS Manager role can manage linked users.
Part 2: Linked Accounts and Shared Balances
Overview
Accounts can be linked in a primary/secondary relationship. A secondary account is always linked to exactly one primary account. When a secondary account has sharedBalance: true, it shares its balance pool with the primary.
Account Variants
Spidr supports four account variants:
| Variant | Description |
|---|---|
individual.primary | Standalone individual account |
individual.secondary | Individual account linked to a primary |
entity.primary | Standalone entity account |
entity.secondary | Entity account linked to a primary |
How Account Linking Works
There is no dedicated "link account" endpoint. Linking happens at account creation time via POST /v1/account/create:
| Field | Type | Description |
|---|---|---|
primaryAccount | ObjectId | The ID of the primary account to link to (triggers secondary creation) |
sharedBalance | boolean | Whether the secondary shares its balance with the primary (default: false, requires primaryAccount) |
Eligibility Rules
For a primary account to accept a secondary:
- Status: Primary must be
ACTIVE - Not anonymous: Primary must not be an anonymous account
- Linkable: Primary must not be flagged as non-linkable (controlled via product config)
- Variant: Primary must be
individual.primaryorentity.primary - Product rules: The primary's product must be configured to permit the secondary's product, and the secondary's product must permit its variant. These product linking rules are configured with Spidr.
Key Account Fields
| Field | Type | Default | Description |
|---|---|---|---|
primaryAccount | ObjectId | (none) | Points to the primary account this is linked to |
sharedBalance | boolean | false | Whether this account shares its balance with the primary |
accountVariant | string | (none) | One of the four account variants |
Shared Balance
sharedBalanceis a boolean set at account creation time- It can only be
truewhenprimaryAccountis provided (i.e., for secondary accounts) - When
true, the secondary account's balance is shared with the primary
linkedAccounts in API Responses
When retrieving an account via GET /v1/account/:id/accountAndCards, the response includes a linkedAccounts array:
| Viewing | linkedAccounts contains |
|---|---|
| Primary account | All secondary accounts where primaryAccount = this account |
| Secondary account | The single primary account this is linked to |
Each entry in linkedAccounts:
| Field | Description |
|---|---|
userId | Owner of the linked account |
accountId | The linked account's ID |
companyId | Company ID |
provider | Card processor: galileo, byop, or loanpro |
status | Account status |
productId | Product ID |
accountFeatures | Array of feature objects (type, value, startDate, endDate) |
accountType | deposit, credit, loan (or the deprecated debit) |
accountVariant | The variant (primary or secondary) |
isSharedBalance | Whether shared balance is enabled |
Note: The bare
GET /v1/account/:iddoes not includelinkedAccounts; it returns anaccountFeaturesarray instead.GET /v1/user/:id/userAndAccountsreturns the user's ownaccountsarray (a different shape that usessharedBalancerather thanisSharedBalance, with nouserId), notlinkedAccounts.
Transaction Handling
includeLinkedAccountTxns
The GET /v1/transaction/getTransactions and GET /v1/transaction/getAllTransHistory endpoints accept an includeLinkedAccountTxns query parameter (default: false).
| Value | Behavior |
|---|---|
false | Return only transactions for the requested account |
true | Also include transactions from any secondary accounts linked to this account (when viewing a primary) |
SST Display: Linked Accounts
Location
The "Account & Cards" tab on the Account show page, below the account details and card list. Only visible when the account has linked accounts.
Table Columns
| Column | Content |
|---|---|
| User ID | Owner of the linked account |
| Account ID | The linked account's ID |
| Status | Account status with color-coded chip |
| Type | Account type (deposit, credit, etc.) |
| Variant | Display-friendly variant name |
| Actions | Show button to navigate to the linked account |
SST Display: Shared Balance
Account Details
For secondary accounts (individual.secondary / entity.secondary), the base account details section shows a "Shared Balance" field with a color-coded chip:
- Yes: green chip
- No: red chip
Transaction Table
The transaction table has several shared-balance-aware features:
| Feature | Behavior |
|---|---|
| Account indicator icon | AccountCircle for primary; PeopleAlt (green) for shared-balance secondary; PeopleAlt (gray) for non-shared secondary |
| Indicator tooltip | The title-cased account-variant label (e.g. "Individual Primary", "Entity Secondary (Shared Balance)", "Individual Secondary (Not Shared Balance)"). |
| "Include Linked Accounts" checkbox | Appears on a primary account only when it has linked accounts and the loaded transactions span more than one distinct accountId; toggles includeLinkedAccountTxns and is checked by default |
| Debit transaction details | Shows a "SHARED BALANCE" field with a Yes (green) / No (red) chip |