Client Accounts
Client accounts represent individual business entities within the system. Each client account has its own settings, users, and business data.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /client-accounts | List client accounts |
| GET | /client-accounts/{id} | Get a specific client account |
| POST | /client-accounts | Create a new client account |
| PUT/PATCH | /client-accounts/{id} | Update a client account |
| DELETE | /client-accounts/{id} | Delete a client account (complete removal) |
| POST | /client-accounts/{id}/reset | Reset a client account (selective data clearing) |
Query Parameters
The GET /client-accounts endpoint supports the following query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| order_by | string | No | Sort order |
| page | integer | No | Page number for pagination (default: 1) |
| per_page | integer | No | Number of items per page (default: 100) |
| has_direct_role | boolean | No | Filter by user’s direct role. Values: true (has direct ClientAccountUser), false (no direct role) |
| is_provider | boolean | No | Filter by provider status. Values: true (is a provider), false (not a provider) |
| provider_type | string | No | Filter by specific provider type. Values: ACCOUNTANT, AUDITOR |
| is_active | boolean | No | Filter by active status. Values: true (active), false (inactive) |
Direct Role vs Contract Access
Client accounts can be accessed in two ways:
- Direct Role: Users have a direct ClientAccountUser association with the client account. This is typical for regular customers who have direct access to their own company.
- Contract Access: Agency users (like accountants and auditors) may have access through a contract between their agency and the client account, without having a direct role.
Filtering Examples
The has_direct_role parameter helps distinguish between these access types:
# Get client accounts where user has a direct role (e.g. customer's own company)
GET /client-accounts?has_direct_role=true
# Get client accounts where user has only contract-based access (e.g. accountant's clients)
GET /client-accounts?has_direct_role=false
# Get all accessible client accounts regardless of access type
GET /client-accounts
# Get only provider accounts (accountants/auditors)
GET /client-accounts?is_provider=true
# Get only accountant accounts
GET /client-accounts?provider_type=ACCOUNTANT
# Get only active accounts
GET /client-accounts?is_active=true
# Combine filters
GET /client-accounts?is_provider=true&provider_type=ACCOUNTANT&is_active=true
Attributes
| Attribute | Type | Description |
|---|---|---|
| id | integer | The unique identifier of the client account |
| created_at | datetime | When the client account was created |
| created_by_id | integer | The ID of the user who created the account |
| updated_at | datetime | When the account was last updated |
| updated_by_id | integer | The ID of the user who last updated the account |
| unique_name | string | Unique identifier for the account |
| display_name | string | Display name for the account |
| is_active | boolean | Whether the account is active |
| accounting_currency | string | The main currency used for accounting |
| organization_id | integer | The ID of the associated organization |
| organization_number | string | The organization number |
| metadata | object | Additional metadata for the account |
| is_provider | boolean | Whether the account is a provider (accountant/auditor) |
| provider_type | string | Type of provider if applicable (ACCOUNTANT/AUDITOR) |
Relationships
| Relationship | Type | Description |
|---|---|---|
| organization | Organization | The associated organization |
| users | [ClientAccountUser] | Users with access to this account |
| provider_contracts | [Contract] | Contracts where this account is the provider |
| client_contracts | [Contract] | Contracts where this account is the client |
| settings | ClientAccountSettings | Historical settings for this account |
| current_settings | ClientAccountSettings | Current active settings |
| statistics | object | Statistical information about the account |
Example Response
{
"id": 1,
"created_at": "2023-05-10T12:00:00Z",
"created_by_id": 1,
"updated_at": "2023-05-10T12:00:00Z",
"updated_by_id": 1,
"unique_name": "acme-corp",
"display_name": "ACME Corporation",
"is_active": true,
"accounting_currency": "EUR",
"organization_id": 1,
"organization_number": "123456789",
"metadata": {
"industry": "Technology",
"size": "Medium"
},
"is_provider": true,
"provider_type": "ACCOUNTANT",
"organization": {
"id": 1,
"name": "ACME Corporation"
},
"current_settings": {
"id": 1,
"active_from": "2023-01-01",
"plan": "ENTERPRISE",
"vat_liable": true,
"project_module": true,
"bank_integration_module": true
},
"statistics": {
"total_users": 10,
"active_projects": 5
}
}
Error Responses
| Status Code | Description |
|---|---|
| 400 | Invalid query parameters |
| 403 | User not authorized to access client account |
| 404 | Client account not found |
Creating Client Accounts
Basic Client Account Creation
Any user can create a basic client account by providing the required organization information:
POST /client-accounts
{
"organization_id": 12345,
"display_name": "New Client Company AS",
"accounting_currency": "NOK"
}
Provider Creating Client Account with Contract
Accountant and auditor providers can create client accounts with contracts in a single request. The contract will be automatically approved since the provider is creating both the client account and the contract:
POST /client-accounts
{
"organization_id": 12345,
"display_name": "New Client Company AS",
"accounting_currency": "NOK",
"client_contracts": [
{
"provider_client_account_id": 123,
"service_provided": "ACCOUNTING",
"start_date": "2025-01-01"
}
]
}
Response:
{
"id": 789,
"display_name": "New Client Company AS",
"organization_id": 12345,
"accounting_currency": "NOK",
"client_contracts": [
{
"id": 456,
"provider_client_account_id": 123,
"client_account_id": 789,
"service_provided": "ACCOUNTING",
"start_date": "2025-01-01",
"approval_status": "APPROVED",
"is_active": true
}
]
}
Authorization Rules
- Basic creation: Any authenticated user can create client accounts
- With contracts: Only provider accounts (accountants/auditors) can create client accounts with contracts
- Organization uniqueness: Each organization can only have one client account
- Provider validation: Users can only create contracts for their own provider accounts
Managing Client Account Users
Client accounts support user management through dedicated endpoints that allow viewing, updating roles, and removing users from client accounts.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /client-accounts/{client_account_id}/users | List all users in a client account |
| PATCH | /client-accounts/{client_account_id}/users/{user_id} | Update a user’s role |
| DELETE | /client-accounts/{client_account_id}/users/{user_id} | Remove a user from the client account |
List Users
Get all active users in a client account with their roles and details.
Authorization: Any user with access to the client account can view the user list.
Request:
GET /client-accounts/123/users
Response:
[
{
"id": 456,
"user_id": 789,
"client_account_id": 123,
"role_id": 3,
"is_active": true,
"created_at": "2023-05-10T12:00:00Z",
"user": {
"id": 789,
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe"
},
"role": {
"id": 3,
"name": "CA",
"display_name": "Client Account Owner"
}
}
]
Update User Role
Update a user’s role within a client account.
Authorization: Only Accountants (AA) and Client Account Owners (CA) can update user roles.
Business Rules:
- Cannot change your own role
- Cannot assign System Administrator (SA) role
- Valid roles: AA (Accountant), CA (Client Account Owner), BK (Bookkeeper), EM (Employee)
Request:
PATCH /client-accounts/123/users/789
Content-Type: application/json
{
"role_id": 2
}
Response:
{
"id": 456,
"user_id": 789,
"client_account_id": 123,
"role_id": 2,
"is_active": true,
"updated_at": "2025-01-10T14:30:00Z",
"updated_by_id": 1,
"user": {
"id": 789,
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe"
},
"role": {
"id": 2,
"name": "AA",
"display_name": "Accountant"
}
}
Remove User
Remove a user from a client account (soft delete - sets is_active to false).
Authorization: Only Accountants (AA) and Client Account Owners (CA) can remove users.
Business Rules:
- Cannot remove yourself from the client account
- Cannot remove the last Client Account Owner (CA)
- User is soft-deleted (is_active set to false) but remains in the database
Request:
DELETE /client-accounts/123/users/789
Response:
{
"id": 456,
"user_id": 789,
"client_account_id": 123,
"role_id": 3,
"is_active": false,
"updated_at": "2025-01-10T14:35:00Z",
"updated_by_id": 1
}
Error Responses
| Status Code | Description |
|---|---|
| 400 | Missing or invalid request body |
| 403 | User not authorized to perform this action |
| 404 | User not found in this client account |
| 422 | Validation error (e.g., trying to remove last CA, change own role) |
Role Types
| Code | Name | Description |
|---|---|---|
| SA | System Administrator | Cannot be assigned via API |
| AA | Accountant | Full access, can manage users |
| CA | Client Account Owner | Full access, can manage users |
| BK | Bookkeeper | Standard bookkeeping access |
| EM | Employee | Limited access |
Deleting and Resetting Client Accounts
Client accounts can be either completely deleted or selectively reset to clear data while preserving the account structure.
Authorization
Both delete and reset operations require elevated permissions:
- AA (Accountant, role_id 2): Can delete/reset their own client accounts
- CA (Client Account Owner, role_id 3): Can delete/reset their own client accounts
- Other roles: Cannot delete or reset client accounts
Confirmation Requirement
All delete and reset operations require a confirmation token to prevent accidental data loss. The confirmation token must match the client account’s unique_name.
Delete Client Account
Complete removal of a client account and ALL associated data. This operation is irreversible.
Endpoint: DELETE /client-accounts/{id}
Request:
DELETE /client-accounts/123
Content-Type: application/json
{
"confirm": "acme-corp",
"dry_run": false
}
What Gets Deleted:
- All transactional data (documents, journal entries, bank transactions, etc.)
- All master data (business partners, items, bank accounts, projects, etc.)
- All integration data (Altinn, Klippa, Zdata, etc.)
- All settings and configurations
- All user associations (ClientAccountUser records)
What Is Preserved:
- Contracts (maintained for both parties’ records)
Response (Success):
{
"success": true,
"operation": "DELETE",
"client_account_id": 123,
"dry_run": false,
"deleted_counts": {
"documents": 450,
"journal_entries": 1200,
"business_partners": 35,
"items": 120,
"bank_transactions": 890,
"client_account_users": 5,
"contracts_as_provider": 0,
"contracts_as_client": 1,
"client_account": 1
},
"message": "Client account deleted successfully"
}
Dry Run Mode:
Use "dry_run": true to see what would be deleted without actually deleting:
DELETE /client-accounts/123
Content-Type: application/json
{
"confirm": "acme-corp",
"dry_run": true
}
The response will include all counts but no data will be deleted, and the message will indicate it was a dry run.
Reset Client Account
Selectively clear data from a client account while preserving the account structure. Choose from three reset levels.
Endpoint: POST /client-accounts/{id}/reset
Reset Levels:
| Level | Description | What Gets Deleted | What Gets Preserved |
|---|---|---|---|
| TRANSACTIONAL | Clear transaction data only | Documents, journal entries, bank transactions, reconciliations, vouchers, posted payments, payment requests, VAT returns, uploaded files, tasks | Master data (business partners, items, bank accounts, projects, departments, tags, assets), settings, user associations, contracts |
| MASTER_DATA | Clear transactions + master data | Everything from TRANSACTIONAL plus: business partners, items, bank accounts, projects, departments, tags, assets, equity transactions | Account structure, settings, user associations, contracts, integration configurations |
| FULL | Clear almost everything | Everything from MASTER_DATA plus: settings, organizational roles, integration data (Altinn, Bank, Zdata), chat channels | Account shell, user associations, contracts |
Request:
POST /client-accounts/123/reset
Content-Type: application/json
{
"level": "MASTER_DATA",
"confirm": "acme-corp",
"dry_run": false
}
Response (Success):
{
"success": true,
"operation": "RESET",
"level": "MASTER_DATA",
"client_account_id": 123,
"dry_run": false,
"reset_counts": {
"documents": 450,
"journal_entries": 1200,
"business_partners": 35,
"items": 120,
"bank_accounts": 5,
"bank_transactions": 890,
"projects": 8,
"departments": 3,
"tags": 12,
"assets": 15
},
"message": "Client account reset successfully at MASTER_DATA level"
}
Dry Run Mode:
Use "dry_run": true to preview what would be reset:
POST /client-accounts/123/reset
Content-Type: application/json
{
"level": "TRANSACTIONAL",
"confirm": "acme-corp",
"dry_run": true
}
Sequence Number Reset
Reset operations also clear sequence numbers to their initial state:
- TRANSACTIONAL level: Resets transaction-related sequence numbers (documents, vouchers, reconciliations, receipts, payments)
- MASTER_DATA level: Additionally resets master data sequence numbers (items, business partners, bank accounts, projects, departments, assets, tags)
- FULL level: Resets all sequence numbers
Error Responses
| Status Code | Description |
|---|---|
| 400 | Invalid request body or missing required parameters |
| 403 | User not authorized to delete/reset this client account |
| 404 | Client account not found |
| 422 | Validation error (e.g., invalid confirmation token, invalid reset level) |
Example Error Response:
{
"error": "Invalid confirmation token",
"message": "The confirmation token must match the client account's unique_name"
}
Best Practices
- Always use dry run first: Run with
"dry_run": trueto preview what will be affected - Verify counts: Review the returned counts in dry run mode before proceeding
- Backup data: Ensure you have backups before performing destructive operations
- Choose appropriate level: Start with TRANSACTIONAL reset if you only need to clear transaction data
- Communicate with users: Inform other users before deleting or resetting shared accounts
- Test in development: Test delete/reset operations in a development environment first
Common Use Cases
| Scenario | Recommended Action |
|---|---|
| Start new accounting year | TRANSACTIONAL reset |
| Clear test data from demo account | MASTER_DATA reset |
| Repurpose existing account | FULL reset |
| Completely remove account | DELETE |
| Remove customer who left | DELETE |
Notes
- Only users with appropriate permissions can access a client account.
- The unique_name must be unique across all client accounts.
- Each organization can only have one client account - attempts to create duplicate accounts will be rejected.
- When updating a client account, only certain fields can be modified (unique_name, display_name, is_active, accounting_currency, metadata).
- Contracts created during client account creation are automatically approved.
- The created_by_id/updated_by_id is automatically set to the authenticated user’s ID.
- All dates are returned in ISO 8601 format.
- Settings are versioned with active_from/active_to dates to track changes over time.