> ## Documentation Index
> Fetch the complete documentation index at: https://apidocs.royalti.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Financial Data & Management

> View earnings, track expenses and revenue, manage accounting, and reconcile financial data in Royalti.io

## Overview

Access comprehensive financial reporting and management tools through the Royalti.io API. View real-time earnings calculations, track expenses and revenue, manage payments, and maintain accurate accounting records across your music catalog.

### Key Features

* **Real-time earnings** - View current earnings and payment status for all users
* **Automatic calculations** - Earnings updated automatically when royalties upload or splits change
* **Expense tracking** - Record costs at any level (user, artist, product, asset, general)
* **Revenue management** - Track additional income sources beyond streaming royalties
* **Transaction history** - Complete audit trail of all financial activity
* **Flexible reporting** - Monthly breakdowns, summaries, and custom date ranges
* **Multi-currency support** - Handle international transactions with automatic USD conversion

## Prerequisites

### Required Data

Before accessing financial features, ensure you have:

* **User accounts** - Collaborators with earnings
* **Configured splits** - Revenue distribution defined with percentages
* **Royalty data uploaded** - Revenue data processed from DSPs/distributors
* **Payment settings** - Bank accounts or payment methods configured (for payments)

### Authentication

<Note>
  All financial endpoints require authentication with a Bearer token.
</Note>

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const headers = {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    };
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }
    ```
  </Tab>
</Tabs>

## Quick Start: Complete Financial Cycle

<Steps>
  <Step title="Check User Earnings">
    View earnings breakdown for a specific user:

    <Tabs>
      <Tab title="Node.js">
        ```javascript theme={null}
        const response = await fetch(
          `https://api.royalti.io/accounting/${userId}/stats`,
          {
            headers: {
              'Authorization': `Bearer ${token}`
            }
          }
        );

        const stats = await response.json();

        console.log('Gross earnings:', stats.Royalty_Share);
        console.log('Amount paid:', stats.paid);
        console.log('Amount due:', stats.due);
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        response = requests.get(
            f'https://api.royalti.io/accounting/{user_id}/stats',
            headers=headers
        )

        stats = response.json()

        print(f"Gross earnings: ${stats['Royalty_Share']}")
        print(f"Amount paid: ${stats['paid']}")
        print(f"Amount due: ${stats['due']}")
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Track an Expense">
    Record costs associated with a product release:

    <Tabs>
      <Tab title="Node.js">
        ```javascript theme={null}
        const response = await fetch('https://api.royalti.io/expense/', {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            title: 'Marketing Campaign',
            type: 'product',
            id: 'product-uuid',
            transactionDate: '2024-03-15',
            currency: 'USD',
            amount: 2500.00,
            amountUSD: 2500.00,
            memo: 'Social media advertising for album release'
          })
        });

        const expense = await response.json();
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        response = requests.post(
            'https://api.royalti.io/expense/',
            headers=headers,
            json={
                'title': 'Marketing Campaign',
                'type': 'product',
                'id': 'product-uuid',
                'transactionDate': '2024-03-15',
                'currency': 'USD',
                'amount': 2500.00,
                'amountUSD': 2500.00,
                'memo': 'Social media advertising for album release'
            }
        )

        expense = response.json()
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Record Additional Revenue">
    Track income beyond streaming royalties:

    <Tabs>
      <Tab title="Node.js">
        ```javascript theme={null}
        const response = await fetch('https://api.royalti.io/revenue/', {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            title: 'Sync Licensing Deal',
            amount: 10000.00,
            currency: 'USD',
            amountUSD: 10000.00,
            transactionDate: '2024-03-20T10:00:00Z',
            ArtistId: 'artist-uuid',
            memo: 'TV commercial licensing'
          })
        });

        const revenue = await response.json();
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        response = requests.post(
            'https://api.royalti.io/revenue/',
            headers=headers,
            json={
                'title': 'Sync Licensing Deal',
                'amount': 10000.00,
                'currency': 'USD',
                'amountUSD': 10000.00,
                'transactionDate': '2024-03-20T10:00:00Z',
                'ArtistId': 'artist-uuid',
                'memo': 'TV commercial licensing'
            }
        )

        revenue = response.json()
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Review Updated Balances">
    Verify accounting reflects all transactions:

    <Tabs>
      <Tab title="Node.js">
        ```javascript theme={null}
        const response = await fetch(
          'https://api.royalti.io/accounting/getcurrentdue?sort=due&order=DESC',
          {
            headers: {
              'Authorization': `Bearer ${token}`
            }
          }
        );

        const { Users } = await response.json();

        Users.forEach(user => {
          console.log(`${user.fullName}: $${user.Due} due`);
        });
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        response = requests.get(
            'https://api.royalti.io/accounting/getcurrentdue?sort=due&order=DESC',
            headers=headers
        )

        data = response.json()
        users = data['Users']

        for user in users:
            print(f"{user['fullName']}: ${user['Due']} due")
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Viewing Earnings & Accounting

### Get User Accounting Statistics

Retrieve comprehensive earnings data for a specific user:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      `https://api.royalti.io/accounting/${userId}/stats`,
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const stats = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        f'https://api.royalti.io/accounting/{user_id}/stats',
        headers=headers
    )

    stats = response.json()
    ```
  </Tab>
</Tabs>

**Response Fields:**

* `Royalty_Share` - Gross earnings from all splits
* `paid` - Total amount paid to user
* `due` - Outstanding balance (Royalty\_Share - paid)

**Query Parameters:**

* `include=royalty` - Include detailed royalty breakdown
* `forceRefresh=true` - Recalculate from source data

**Example Response:**

```json theme={null}
{
  "Royalty_Share": 1135.28,
  "paid": 100.00,
  "due": 1035.28
}
```

### Get Detailed Royalty Breakdown

Include royalty summary for streams, downloads, and rates:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      `https://api.royalti.io/accounting/${userId}/stats?include=royalty`,
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const stats = await response.json();

    console.log('Total streams:', stats.royaltySummary.Streams);
    console.log('Stream royalty:', stats.royaltySummary.Streams_Royalty);
    console.log('Total downloads:', stats.royaltySummary.Downloads);
    console.log('Download royalty:', stats.royaltySummary.Downloads_Royalty);
    console.log('Rate per 1K:', stats.royaltySummary.RatePer1K);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        f'https://api.royalti.io/accounting/{user_id}/stats?include=royalty',
        headers=headers
    )

    stats = response.json()

    if 'royaltySummary' in stats:
        summary = stats['royaltySummary']
        print(f"Total streams: {summary['Streams']}")
        print(f"Stream royalty: ${summary['Streams_Royalty']}")
        print(f"Total downloads: {summary['Downloads']}")
        print(f"Download royalty: ${summary['Downloads_Royalty']}")
    ```
  </Tab>
</Tabs>

### Current Balances for All Users

Get list of all users with their outstanding balances:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/getcurrentdue?sort=due&order=DESC&page=1&size=20',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const { Users, totalUsers, page, totalPages } = await response.json();

    Users.forEach(user => {
      console.log(`${user.fullName}: $${user.Due} due`);
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/getcurrentdue?sort=due&order=DESC',
        headers=headers
    )

    data = response.json()

    for user in data['Users']:
        print(f"{user['fullName']}: ${user['Due']} due")
    ```
  </Tab>
</Tabs>

**Query Parameters:**

* `q` - Search by user name
* `page` - Page number (default: 1)
* `size` - Page size (default: 10, max: 100)
* `sort` - Sort field: `gross`, `net`, `paid`, `due` (default: `due`)
* `order` - Sort order: `ASC` or `DESC` (default: `DESC`)

**Response Fields per User:**

```json theme={null}
{
  "id": "user-id",
  "firstName": "John",
  "lastName": "Doe",
  "fullName": "John Doe",
  "email": "john@example.com",
  "TenantUserId": "tenant-user-id",
  "Gross": 2500.75,
  "Net": 2250.68,
  "Paid": 1500.00,
  "Due": 750.68,
  "paymentRequested": false,
  "paymentRequestId": null
}
```

### Total Outstanding for Workspace

Get aggregate due amount across all users:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/gettotaldue',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const total = await response.json();

    console.log('Total gross:', total.totalGross);
    console.log('Total paid:', total.totalPaid);
    console.log('Total due:', total.totalDue);
    console.log('User count:', total.userCount);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/gettotaldue',
        headers=headers
    )

    total = response.json()

    print(f"Total gross: ${total['totalGross']}")
    print(f"Total paid: ${total['totalPaid']}")
    print(f"Total due: ${total['totalDue']}")
    print(f"User count: {total['userCount']}")
    ```
  </Tab>
</Tabs>

**Response Example:**

```json theme={null}
{
  "message": "success",
  "totalGross": 150000.50,
  "totalPaid": 100000.00,
  "totalDue": 50000.50,
  "userCount": 125
}
```

### Transaction History

Get paginated list of all financial transactions:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/transactions?page=1&size=20',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const { transaction, currentPage, totalPages, totalItem } = await response.json();

    transaction.forEach(txn => {
      console.log(`${txn.type}: $${txn.amount} - ${txn.TenantUser.fullName}`);
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/transactions?page=1&size=20',
        headers=headers
    )

    data = response.json()
    transactions = data['transaction']

    for txn in transactions:
        print(f"{txn['type']}: ${txn['amount']} - {txn['TenantUser']['fullName']}")
    ```
  </Tab>
</Tabs>

**Query Parameters:**

* `page` - Page number (default: 1)
* `size` - Items per page (default: 10, max: 100)
* `start` - Start date filter (ISO format: YYYY-MM-DD)
* `end` - End date filter (ISO format: YYYY-MM-DD)

**Transaction Types:**

* `payment` - Payment made to user
* `revenue` - Revenue received
* `expense` - Expense recorded
* `paymentRequest` - Payment request created

**Filter by Date Range:**

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/transactions?start=2024-01-01&end=2024-12-31',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/transactions?start=2024-01-01&end=2024-12-31',
        headers=headers
    )

    data = response.json()
    ```
  </Tab>
</Tabs>

### Transaction Summary

Get aggregated totals across all transaction types:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/transactions/summary',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const { summary } = await response.json();

    console.log('Total payments:', summary.totalPayments);
    console.log('Total revenues:', summary.totalRevenues);
    console.log('Total expenses:', summary.totalExpenses);
    console.log('Net amount:', summary.netAmount);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/transactions/summary',
        headers=headers
    )

    data = response.json()
    summary = data['summary']

    print(f"Total payments: ${summary['totalPayments']}")
    print(f"Total revenues: ${summary['totalRevenues']}")
    print(f"Total expenses: ${summary['totalExpenses']}")
    print(f"Net amount: ${summary['netAmount']}")
    ```
  </Tab>
</Tabs>

**Response Example:**

```json theme={null}
{
  "message": "success",
  "summary": {
    "totalPayments": 50000.00,
    "totalRevenues": 125000.50,
    "totalExpenses": 15000.25,
    "netAmount": 60000.25
  }
}
```

<Note>
  The summary provides all-time totals for the workspace. Use the monthly breakdown endpoint for time-series analysis.
</Note>

### Monthly Transaction Breakdown

Analyze transactions by month with type breakdown:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/transactions/monthly?start=2024-01-01&stop=2024-12-31',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const monthlyData = await response.json();

    monthlyData.forEach(month => {
      console.log(`${month.month}:`);
      console.log(`  Payments: $${month.transactions.payment}`);
      console.log(`  Revenue: $${month.transactions.revenue}`);
      console.log(`  Expenses: $${month.transactions.expense}`);
      console.log(`  Net: $${month.transactions.net}`);
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/transactions/monthly?start=2024-01-01&stop=2024-12-31',
        headers=headers
    )

    monthly_data = response.json()

    for month in monthly_data:
        print(f"{month['month']}:")
        print(f"  Payments: ${month['transactions']['payment']}")
        print(f"  Revenue: ${month['transactions']['revenue']}")
        print(f"  Expenses: ${month['transactions']['expense']}")
        print(f"  Net: ${month['transactions']['net']}")
    ```
  </Tab>
</Tabs>

**Query Parameters:**

* `start` - Start date (ISO format: YYYY-MM-DD)
* `stop` - End date (ISO format: YYYY-MM-DD)

**Response Format:**

```json theme={null}
[
  {
    "month": "2024-08-01",
    "transactions": {
      "payment": 5000.00,
      "revenue": 12500.50,
      "expense": 1500.25,
      "net": 6000.25
    }
  }
]
```

## Expense Management

Track costs associated with releases, artists, and operations. Expenses reduce user earnings in accounting calculations.

### Flexible Expense Association

Expenses can be associated with different types of entities in your catalog:

| Type      | Description                    | Use Case                                |
| --------- | ------------------------------ | --------------------------------------- |
| `user`    | Associate with a specific user | Personal expenses, reimbursements       |
| `artist`  | Associate with an artist       | Recording sessions, promotional costs   |
| `product` | Associate with an album/EP     | Marketing campaigns, manufacturing      |
| `asset`   | Associate with a single track  | Mastering, mixing, feature artist fees  |
| `general` | Not associated with any entity | Office expenses, software subscriptions |

**How It Works:**

* Specify the `type` field to indicate the entity type
* Provide the `id` field with the entity's UUID
* For `general` expenses, omit the `id` field

This flexible system allows you to:

* Track costs at any level of granularity
* Generate expense reports by artist, product, or asset
* Allocate expenses to the appropriate earnings calculations

### Create Product Expense

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch('https://api.royalti.io/expense/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Marketing Campaign',
        type: 'product',
        id: 'product-uuid',
        transactionDate: '2024-03-15',
        currency: 'USD',
        amount: 2500.00,
        amountUSD: 2500.00,
        conversionRate: 1.0,
        memo: 'Social media advertising for album release',
        split: [
          { user: 'user-id-1', share: 60 },
          { user: 'user-id-2', share: 40 }
        ]
      })
    });

    const expense = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/expense/',
        headers=headers,
        json={
            'title': 'Marketing Campaign',
            'type': 'product',
            'id': 'product-uuid',
            'transactionDate': '2024-03-15',
            'currency': 'USD',
            'amount': 2500.00,
            'amountUSD': 2500.00,
            'memo': 'Social media advertising for album release',
            'split': [
                {'user': 'user-id-1', 'share': 60},
                {'user': 'user-id-2', 'share': 40}
            ]
        }
    )

    expense = response.json()
    ```
  </Tab>
</Tabs>

### Create Artist Expense

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch('https://api.royalti.io/expense/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Studio Recording Session',
        type: 'artist',
        id: 'artist-uuid',
        transactionDate: '2024-02-20',
        currency: 'USD',
        amount: 5000.00,
        amountUSD: 5000.00,
        memo: 'Recording sessions for new album'
      })
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/expense/',
        headers=headers,
        json={
            'title': 'Studio Recording Session',
            'type': 'artist',
            'id': 'artist-uuid',
            'transactionDate': '2024-02-20',
            'currency': 'USD',
            'amount': 5000.00,
            'amountUSD': 5000.00,
            'memo': 'Recording sessions for new album'
        }
    )

    expense = response.json()
    ```
  </Tab>
</Tabs>

### Create Asset Expense

Track costs for individual tracks or recordings:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch('https://api.royalti.io/expense/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Mastering Services',
        type: 'asset',
        id: 'asset-uuid',
        transactionDate: '2024-03-10',
        currency: 'USD',
        amount: 800.00,
        amountUSD: 800.00,
        memo: 'Professional mastering for single track'
      })
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/expense/',
        headers=headers,
        json={
            'title': 'Mastering Services',
            'type': 'asset',
            'id': 'asset-uuid',
            'transactionDate': '2024-03-10',
            'currency': 'USD',
            'amount': 800.00,
            'amountUSD': 800.00,
            'memo': 'Professional mastering for single track'
        }
    )

    expense = response.json()
    ```
  </Tab>
</Tabs>

### Create General Expense

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch('https://api.royalti.io/expense/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Legal Consultation',
        type: 'general',
        transactionDate: '2024-03-01',
        currency: 'USD',
        amount: 1500.00,
        amountUSD: 1500.00,
        memo: 'Contract review and negotiation'
      })
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/expense/',
        headers=headers,
        json={
            'title': 'Legal Consultation',
            'type': 'general',
            'transactionDate': '2024-03-01',
            'currency': 'USD',
            'amount': 1500.00,
            'amountUSD': 1500.00,
            'memo': 'Contract review and negotiation'
        }
    )

    expense = response.json()
    ```
  </Tab>
</Tabs>

### List Expenses

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/expense/?include=Artist,Product,Asset&page=1&size=20',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const { expenses } = await response.json();

    expenses.forEach(expense => {
      console.log(`${expense.title}: $${expense.amountUSD}`);
      if (expense.Artist) console.log(`  Artist: ${expense.Artist.name}`);
      if (expense.Product) console.log(`  Product: ${expense.Product.title}`);
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/expense/?include=Artist,Product,Asset&page=1&size=20',
        headers=headers
    )

    data = response.json()
    expenses = data['expenses']

    for expense in expenses:
        print(f"{expense['title']}: ${expense['amountUSD']}")
        if 'Artist' in expense and expense['Artist']:
            print(f"  Artist: {expense['Artist']['name']}")
        if 'Product' in expense and expense['Product']:
            print(f"  Product: {expense['Product']['title']}")
    ```
  </Tab>
</Tabs>

### Expense Splits

Distribute expenses among multiple users:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    {
      split: [
        { user: 'user-uuid-1', share: 50 },  // 50% of expense
        { user: 'user-uuid-2', share: 30 },  // 30% of expense
        { user: 'user-uuid-3', share: 20 }   // 20% of expense
      ]
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    expense_data = {
        'split': [
            {'user': 'user-uuid-1', 'share': 50},  # 50% of expense
            {'user': 'user-uuid-2', 'share': 30},  # 30% of expense
            {'user': 'user-uuid-3', 'share': 20}   # 20% of expense
        ]
    }
    ```
  </Tab>
</Tabs>

<Note>
  Expense splits reduce user earnings in accounting calculations. The total share should equal 100.
</Note>

### Bulk Expense Creation

Create multiple expenses in a single request:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const expenseData = [
      {
        title: 'Marketing - Product A',
        type: 'product',
        id: 'product-a-uuid',
        transactionDate: '2024-03-15',
        currency: 'USD',
        amount: 1000.00,
        amountUSD: 1000.00
      },
      {
        title: 'Marketing - Product B',
        type: 'product',
        id: 'product-b-uuid',
        transactionDate: '2024-03-15',
        currency: 'USD',
        amount: 1500.00,
        amountUSD: 1500.00
      }
    ];

    const response = await fetch('https://api.royalti.io/expense/bulk', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ expenses: expenseData })
    });

    const result = await response.json();
    console.log('Created:', result.data.created);
    console.log('Failed:', result.data.failed);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    expense_data = [
        {
            'title': 'Marketing - Product A',
            'type': 'product',
            'id': 'product-a-uuid',
            'transactionDate': '2024-03-15',
            'currency': 'USD',
            'amount': 1000.00,
            'amountUSD': 1000.00
        },
        {
            'title': 'Marketing - Product B',
            'type': 'product',
            'id': 'product-b-uuid',
            'transactionDate': '2024-03-15',
            'currency': 'USD',
            'amount': 1500.00,
            'amountUSD': 1500.00
        }
    ]

    response = requests.post(
        'https://api.royalti.io/expense/bulk',
        headers=headers,
        json={'expenses': expense_data}
    )

    result = response.json()
    print(f"Created: {result['data']['created']}")
    print(f"Failed: {result['data']['failed']}")
    ```
  </Tab>
</Tabs>

## Revenue Management

Track additional income sources beyond streaming royalties.

### Create Sync Licensing Revenue

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch('https://api.royalti.io/revenue/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Sync Licensing Deal',
        amount: 10000.00,
        currency: 'USD',
        amountUSD: 10000.00,
        transactionDate: '2024-03-20T10:00:00Z',
        ArtistId: 'artist-uuid',
        memo: 'TV commercial licensing',
        splits: [
          { user: 'user-id-1', share: 60 },
          { user: 'user-id-2', share: 40 }
        ]
      })
    });

    const revenue = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/revenue/',
        headers=headers,
        json={
            'title': 'Sync Licensing Deal',
            'amount': 10000.00,
            'currency': 'USD',
            'amountUSD': 10000.00,
            'transactionDate': '2024-03-20T10:00:00Z',
            'ArtistId': 'artist-uuid',
            'memo': 'TV commercial licensing',
            'splits': [
                {'user': 'user-id-1', 'share': 60},
                {'user': 'user-id-2', 'share': 40}
            ]
        }
    )

    revenue = response.json()
    ```
  </Tab>
</Tabs>

### Create Merchandise Revenue

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch('https://api.royalti.io/revenue/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Merchandise Sales - Q1',
        amount: 5000.00,
        currency: 'USD',
        amountUSD: 5000.00,
        transactionDate: '2024-03-31T23:59:59Z',
        memo: 'T-shirts and posters sales'
      })
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/revenue/',
        headers=headers,
        json={
            'title': 'Merchandise Sales - Q1',
            'amount': 5000.00,
            'currency': 'USD',
            'amountUSD': 5000.00,
            'transactionDate': '2024-03-31T23:59:59Z',
            'memo': 'T-shirts and posters sales'
        }
    )

    revenue = response.json()
    ```
  </Tab>
</Tabs>

### List Revenue

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/revenue/?include=Artist&page=1&size=20',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const { revenues } = await response.json();

    revenues.forEach(revenue => {
      console.log(`${revenue.title}: $${revenue.amountUSD}`);
      if (revenue.Artist) console.log(`  Artist: ${revenue.Artist.name}`);
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/revenue/?include=Artist&page=1&size=20',
        headers=headers
    )

    data = response.json()
    revenues = data['revenues']

    for revenue in revenues:
        print(f"{revenue['title']}: ${revenue['amountUSD']}")
        if 'Artist' in revenue and revenue['Artist']:
            print(f"  Artist: {revenue['Artist']['name']}")
    ```
  </Tab>
</Tabs>

### Bulk Revenue Creation

Create multiple revenue records in a single request:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const revenueData = [
      {
        title: 'Sync Deal A',
        amount: 5000.00,
        currency: 'USD',
        amountUSD: 5000.00,
        transactionDate: '2024-03-01',
        ArtistId: 'artist-a-uuid'
      },
      {
        title: 'Sync Deal B',
        amount: 7500.00,
        currency: 'USD',
        amountUSD: 7500.00,
        transactionDate: '2024-03-15',
        ArtistId: 'artist-b-uuid'
      }
    ];

    const response = await fetch('https://api.royalti.io/revenue/bulk', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ revenues: revenueData })
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    revenue_data = [
        {
            'title': 'Sync Deal A',
            'amount': 5000.00,
            'currency': 'USD',
            'amountUSD': 5000.00,
            'transactionDate': '2024-03-01',
            'ArtistId': 'artist-a-uuid'
        },
        {
            'title': 'Sync Deal B',
            'amount': 7500.00,
            'currency': 'USD',
            'amountUSD': 7500.00,
            'transactionDate': '2024-03-15',
            'ArtistId': 'artist-b-uuid'
        }
    ]

    response = requests.post(
        'https://api.royalti.io/revenue/bulk',
        headers=headers,
        json={'revenues': revenue_data}
    )

    result = response.json()
    ```
  </Tab>
</Tabs>

## Accounting Operations

### When to Refresh Accounting Data

Accounting data is automatically calculated when:

* Royalty files are uploaded and processed
* Splits are created or modified
* Payments are recorded
* Expenses or revenue entries are created

You may want to manually refresh when:

* You've made multiple split changes
* You need guaranteed latest data
* You suspect calculations are out of sync

### Refresh for Specific User

Request updated calculations for a single user:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      `https://api.royalti.io/accounting/users/${userId}/recalculate?forceRefresh=true`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const result = await response.json();

    console.log('Status:', result.message);
    console.log('Job ID:', result.jobId);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        f'https://api.royalti.io/accounting/users/{user_id}/recalculate?forceRefresh=true',
        headers=headers
    )

    result = response.json()
    print(f"Status: {result['message']}")
    print(f"Job ID: {result['jobId']}")
    ```
  </Tab>
</Tabs>

**Query Parameters:**

* `forceRefresh=true` - Force recalculation even if data is recent

**Response:**

```json theme={null}
{
  "message": "User accounting update queued successfully",
  "jobId": "job-uuid-123",
  "userId": "tenant-user-id",
  "status": "queued"
}
```

### Refresh All Users in Workspace

Request recalculation for all users:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/tenant/recalculate?batchSize=100',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const result = await response.json();

    console.log('Status:', result.message);
    console.log('Job ID:', result.jobId);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.royalti.io/accounting/tenant/recalculate?batchSize=100',
        headers=headers
    )

    result = response.json()

    print(f"Status: {result['message']}")
    print(f"Job ID: {result['jobId']}")
    ```
  </Tab>
</Tabs>

**Query Parameters:**

* `batchSize` - Users per batch (default: 100, min: 1, max: 500)

**Response:**

```json theme={null}
{
  "message": "Tenant accounting update queued successfully",
  "jobId": "job-uuid-456",
  "tenantId": 123,
  "status": "queued",
  "info": {
    "batchSize": 100,
    "estimatedTime": "~5 minutes for 500 users"
  }
}
```

<Info>
  For workspaces with many users (100+), recalculation is processed in batches to ensure reliability. Check the status endpoint to monitor progress.
</Info>

### Immediate Refresh (Small Workspaces)

For small workspaces with fewer than 100 users, you can use the immediate refresh:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/refresh',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const result = await response.json();

    console.log('Processed:', result.processedCount);
    console.log('Total users:', result.totalUsers);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/refresh',
        headers=headers
    )

    result = response.json()

    print(f"Processed: {result['processedCount']}")
    print(f"Total users: {result['totalUsers']}")
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
{
  "message": "success",
  "processedCount": 125,
  "totalUsers": 125
}
```

<Warning>
  This endpoint processes all users immediately. For workspaces with 100+ users, use the batched recalculate endpoint instead to avoid timeouts.
</Warning>

### Check Recalculation Status

Monitor the progress of recalculation operations:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      `https://api.royalti.io/accounting/queue/status?jobId=${jobId}`,
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const status = await response.json();

    console.log('Job state:', status.state);
    console.log('Progress:', status.progress + '%');
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        f'https://api.royalti.io/accounting/queue/status?jobId={job_id}',
        headers=headers
    )

    status = response.json()

    print(f"Job state: {status['state']}")
    print(f"Progress: {status['progress']}%")
    ```
  </Tab>
</Tabs>

**Job States:**

* `waiting` - Job queued, not yet started
* `active` - Currently processing
* `completed` - Successfully finished
* `failed` - Encountered an error
* `delayed` - Temporarily delayed, will retry

**Response Example:**

```json theme={null}
{
  "jobId": "job-uuid-123",
  "state": "active",
  "progress": 45.5,
  "data": {
    "triggeredBy": "manual",
    "timestamp": "2024-08-11T10:30:00Z",
    "userCount": 100
  },
  "timestamps": {
    "created": 1723370000000,
    "processed": 1723370050000,
    "finished": null
  }
}
```

### Queue Overview

View overall queue status without specifying a job ID:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/queue/status',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const overview = await response.json();

    console.log('Waiting jobs:', overview.queue.waiting);
    console.log('Active jobs:', overview.queue.active);
    console.log('Completed:', overview.queue.completed);
    console.log('Failed:', overview.queue.failed);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/queue/status',
        headers=headers
    )

    overview = response.json()

    print(f"Waiting jobs: {overview['queue']['waiting']}")
    print(f"Active jobs: {overview['queue']['active']}")
    print(f"Completed: {overview['queue']['completed']}")
    print(f"Failed: {overview['queue']['failed']}")
    ```
  </Tab>
</Tabs>

### Statistics Pipeline

Refresh all statistics and accounting data in the correct order:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      'https://api.royalti.io/accounting/refreshstats',
      {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      }
    );

    const result = await response.json();

    console.log('Status:', result.message);
    console.log('Flow ID:', result.flowId);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        'https://api.royalti.io/accounting/refreshstats',
        headers=headers
    )

    result = response.json()

    print(f"Status: {result['message']}")
    print(f"Flow ID: {result['flowId']}")
    ```
  </Tab>
</Tabs>

**Response:**

```json theme={null}
{
  "message": "Stats and accounting refresh queued successfully",
  "flowId": "flow-uuid-789",
  "tenantId": 123,
  "status": "queued",
  "info": {
    "triggeredBy": "manual",
    "executionOrder": "Product Stats → Asset Stats → Artist Stats → Accounting"
  }
}
```

<Info>
  This endpoint ensures all statistics are recalculated in the correct dependency order. Use this after bulk data uploads or major catalog changes.
</Info>

## Multi-Currency Handling

All financial records support multi-currency transactions with automatic USD conversion:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    {
      currency: 'EUR',
      amount: 1000.00,        // Amount in EUR
      amountUSD: 1090.00,     // USD equivalent
      conversionRate: 1.09    // EUR to USD rate
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    {
        'currency': 'EUR',
        'amount': 1000.00,        # Amount in EUR
        'amountUSD': 1090.00,     # USD equivalent
        'conversionRate': 1.09    # EUR to USD rate
    }
    ```
  </Tab>
</Tabs>

**Example: Euro Payment:**

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const eurAmount = 1000;
    const eurToUsdRate = 1.09;  // 1 EUR = 1.09 USD
    const usdAmount = eurAmount * eurToUsdRate;

    const response = await fetch('https://api.royalti.io/payment/', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        user: 'user-uuid',
        title: 'Euro Payment',
        transactionDate: '2024-03-15',
        currency: 'EUR',
        amount: eurAmount,      // 1000
        amountUSD: usdAmount,   // 1090
        conversionRate: eurToUsdRate  // 1.09
      })
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    eur_amount = 1000
    eur_to_usd_rate = 1.09  # 1 EUR = 1.09 USD
    usd_amount = eur_amount * eur_to_usd_rate

    response = requests.post(
        'https://api.royalti.io/payment/',
        headers=headers,
        json={
            'user': 'user-uuid',
            'title': 'Euro Payment',
            'transactionDate': '2024-03-15',
            'currency': 'EUR',
            'amount': eur_amount,       # 1000
            'amountUSD': usd_amount,    # 1090
            'conversionRate': eur_to_usd_rate  # 1.09
        }
    )

    payment = response.json()
    ```
  </Tab>
</Tabs>

<Info>
  The system uses `amountUSD` for all accounting calculations to ensure consistency across currencies.
</Info>

## Best Practices

### Data Accuracy

1. **Trust automatic calculations** - The system updates accounting when royalties upload or splits change
2. **Use forceRefresh sparingly** - Only when you need guaranteed fresh data
3. **Validate splits first** - Ensure splits total 100% before expecting accurate earnings
4. **Regular reconciliation** - Compare accounting data with actual payments monthly
5. **Verify amounts** - Always double-check USD conversion rates
6. **Detailed memos** - Include transaction context for audit trails

### Performance Optimization

1. **Use default cached data** - Faster response times for most queries
2. **Batch operations** - Use bulk endpoints for multiple records
3. **Monitor queue status** - Track long-running recalculation operations
4. **Paginate results** - Use reasonable page sizes (10-50 items)
5. **Async processing** - Don't wait for recalculation to complete

### Reporting Workflows

1. **Use date filters** - Filter transactions by specific periods for reports
2. **Export for analysis** - Use transaction endpoints for external reporting tools
3. **Monitor monthly trends** - Track revenue and payment patterns over time
4. **Check user balances** - Regularly review who is owed payment
5. **Weekly reviews** - Check user balances and pending items
6. **Monthly cycles** - Establish consistent payment schedules
7. **Quarterly audits** - Reconcile all transactions against external records

### Error Handling

Always implement robust error handling for financial operations:

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    async function refreshUserAccounting(userId, forceRefresh = false) {
      try {
        const url = `https://api.royalti.io/accounting/users/${userId}/recalculate?forceRefresh=${forceRefresh}`;

        const response = await fetch(url, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });

        if (!response.ok) {
          const error = await response.json();
          throw new Error(`Refresh failed: ${error.message}`);
        }

        const result = await response.json();

        // Monitor job status
        const jobId = result.jobId;
        const statusUrl = `https://api.royalti.io/accounting/queue/status?jobId=${jobId}`;

        let completed = false;
        while (!completed) {
          await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds

          const statusResponse = await fetch(statusUrl, {
            headers: { 'Authorization': `Bearer ${token}` }
          });

          const status = await statusResponse.json();

          if (status.state === 'completed') {
            completed = true;
            console.log('Refresh completed successfully');
          } else if (status.state === 'failed') {
            throw new Error('Refresh job failed');
          }

          console.log(`Progress: ${status.progress}%`);
        }

        return true;

      } catch (error) {
        console.error('Accounting refresh failed:', error.message);
        throw error;
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests
    import time

    def refresh_user_accounting(user_id, force_refresh=False):
        try:
            url = f'https://api.royalti.io/accounting/users/{user_id}/recalculate'
            params = {'forceRefresh': force_refresh}

            response = requests.post(url, headers=headers, params=params)
            response.raise_for_status()

            result = response.json()
            job_id = result['jobId']

            # Monitor job status
            status_url = f'https://api.royalti.io/accounting/queue/status'
            completed = False

            while not completed:
                time.sleep(2)  # Wait 2 seconds

                status_response = requests.get(
                    status_url,
                    headers=headers,
                    params={'jobId': job_id}
                )
                status = status_response.json()

                if status['state'] == 'completed':
                    completed = True
                    print('Refresh completed successfully')
                elif status['state'] == 'failed':
                    raise Exception('Refresh job failed')

                print(f"Progress: {status['progress']}%")

            return True

        except Exception as e:
            print(f'Accounting refresh failed: {e}')
            raise
    ```
  </Tab>
</Tabs>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Earnings don't match expected amount">
    **Checklist:**

    * Verify split configurations are active
    * Check split date ranges include relevant periods
    * Review conditional split logic (territory, DSP-specific splits)
    * Ensure royalty data uploaded successfully
    * Check for expenses reducing earnings

    **Solutions:**

    1. Check user stats: `GET /accounting/{userId}/stats`
    2. Force refresh: `GET /accounting/{userId}/stats?forceRefresh=true`
    3. Verify splits: `GET /split?userId={userId}`
    4. Check royalty data: `GET /royalty?userId={userId}`
    5. Review expenses: `GET /expense?userId={userId}`
  </Accordion>

  <Accordion title="Data seems outdated">
    **Possible causes:**

    * Recent split changes not yet reflected
    * Royalty file just uploaded
    * Manual refresh needed
    * Cache delay

    **Solutions:**

    1. Use `forceRefresh=true` parameter
    2. Check recent uploads: `GET /file?status=completed`
    3. Verify split changes saved: `GET /split/{splitId}`
    4. Request recalculation: `POST /accounting/users/{userId}/recalculate`
  </Accordion>

  <Accordion title="Refresh job stuck or failed">
    **Check job status:**

    ```javascript theme={null}
    const status = await fetch(
      `https://api.royalti.io/accounting/queue/status?jobId=${jobId}`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );
    ```

    **Common causes:**

    * Invalid split data (doesn't total 100%)
    * Missing royalty data
    * Database connection issues
    * Large dataset processing

    **Solutions:**

    1. Check error details in job status
    2. Verify split configurations
    3. Retry with smaller batch size
    4. Contact support if error persists

    **Expected Processing Times:**

    * Small workspaces (\<100 users): 1-2 minutes
    * Medium workspaces (100-1000 users): 2-10 minutes
    * Large workspaces (1000+ users): 10-30 minutes
  </Accordion>

  <Accordion title="User missing from current due list">
    **Checklist:**

    * User has at least one active split
    * Split date ranges include current period
    * Asset/Product has royalty data uploaded
    * Split percentages are valid (0-100)
    * User actually has positive balance

    **Verify:**

    1. Check user splits: `GET /split?userId={userId}`
    2. Check user stats: `GET /accounting/{userId}/stats`
    3. Verify user exists: `GET /user/{userId}`
    4. Force recalculation if needed
  </Accordion>

  <Accordion title="Transaction totals don't match">
    **Reconciliation steps:**

    ```javascript theme={null}
    // Get transaction summary
    const summary = await fetch(
      'https://api.royalti.io/accounting/transactions/summary',
      { headers: { 'Authorization': `Bearer ${token}` } }
    );

    // Get current due total
    const due = await fetch(
      'https://api.royalti.io/accounting/gettotaldue',
      { headers: { 'Authorization': `Bearer ${token}` } }
    );

    // Compare values
    const summaryData = await summary.json();
    const dueData = await due.json();

    console.log('Summary total paid:', summaryData.summary.totalPayments);
    console.log('Accounting total paid:', dueData.totalPaid);
    ```

    **If mismatched:**

    1. Check for deleted payments
    2. Verify all payments recorded correctly
    3. Review expenses and revenue entries
    4. Force full workspace refresh
  </Accordion>

  <Accordion title="Currency conversion incorrect">
    **Common Mistakes:**

    * Wrong conversion direction (USD/EUR vs EUR/USD)
    * Missing conversionRate
    * amountUSD doesn't match calculation

    **Correct Example:**

    ```javascript theme={null}
    const eurAmount = 1000;
    const eurToUsdRate = 1.09;  // 1 EUR = 1.09 USD
    const usdAmount = eurAmount * eurToUsdRate;

    {
      currency: 'EUR',
      amount: eurAmount,      // 1000
      amountUSD: usdAmount,   // 1090
      conversionRate: eurToUsdRate  // 1.09
    }
    ```
  </Accordion>

  <Accordion title="Expense not reducing user earnings">
    **Checklist:**

    * Expense split configured correctly
    * User IDs in split are valid
    * Share percentages total 100
    * Expense transaction date is within accounting period

    **Solutions:**

    1. Verify expense: `GET /expense/{id}`
    2. Check split configuration in expense record
    3. Force user recalculation: `POST /accounting/users/{userId}/recalculate`
    4. Review accounting stats: `GET /accounting/{userId}/stats?forceRefresh=true`
  </Accordion>

  <Accordion title="Revenue not increasing user earnings">
    **Checklist:**

    * Revenue splits configured correctly
    * User IDs in splits are valid
    * Share percentages total 100
    * Revenue amount is positive

    **Solutions:**

    1. Verify revenue: `GET /revenue/{id}`
    2. Check split configuration
    3. Force user recalculation: `POST /accounting/users/{userId}/recalculate`
    4. Review accounting stats: `GET /accounting/{userId}/stats?forceRefresh=true`
  </Accordion>
</AccordionGroup>

## API Reference

For complete endpoint documentation, see:

**Accounting & Earnings:**

* [GET /accounting/{id}/stats](/api-reference/accounting/get-accounting-id-stats) - User earnings statistics
* [GET /accounting/getcurrentdue](/api-reference/accounting/get-accounting-getcurrentdue) - Users with balances
* [GET /accounting/gettotaldue](/api-reference/accounting/get-accounting-gettotaldue) - Workspace total due
* [GET /accounting/transactions](/api-reference/accounting/get-accounting-transactions) - List transactions
* [GET /accounting/transactions/summary](/api-reference/accounting/get-accounting-transactions-summary) - Aggregate summary
* [GET /accounting/transactions/monthly](/api-reference/accounting/get-accounting-transactions-monthly) - Monthly breakdown

**Refresh Operations:**

* [GET /accounting/refresh](/api-reference/accounting/get-accounting-refresh) - Immediate refresh (small workspaces)
* [GET /accounting/refreshstats](/api-reference/accounting/get-accounting-refreshstats) - Statistics pipeline
* [POST /accounting/users/{id}/recalculate](/api-reference/accounting/post-accounting-users-id-recalculate) - Single user refresh
* [POST /accounting/tenant/recalculate](/api-reference/accounting/post-accounting-tenant-recalculate) - Workspace refresh
* [GET /accounting/queue/status](/api-reference/accounting/get-accounting-queue-status) - Monitor progress

**Expenses:**

* [POST /expense](/api-reference/expense/post-expense) - Create expense
* [GET /expense](/api-reference/expense/get-expense) - List expenses
* [GET /expense/{id}](/api-reference/expense/get-expense-id) - Get expense details
* [PUT /expense/{id}](/api-reference/expense/put-expense-id) - Update expense
* [POST /expense/bulk](/api-reference/expense/post-expense-bulk) - Bulk create
* [POST /expense/bulk-delete](/api-reference/expense/post-expense-bulk-delete) - Bulk delete

**Revenue:**

* [POST /revenue](/api-reference/revenue/post-revenue) - Create revenue
* [GET /revenue](/api-reference/revenue/get-revenue) - List revenue
* [GET /revenue/{id}](/api-reference/revenue/get-revenue-id) - Get revenue details
* [PUT /revenue/{id}](/api-reference/revenue/put-revenue-id) - Update revenue
* [DELETE /revenue/{id}](/api-reference/revenue/delete-revenue-id) - Delete revenue
* [POST /revenue/bulk](/api-reference/revenue/post-revenue-bulk) - Bulk create
* [POST /revenue/bulk-delete](/api-reference/revenue/post-revenue-bulk-delete) - Bulk delete

**Related Guides:**

* [Payment Processing](/guides/payment-processing) - Detailed payment workflows and VertoFX integration
* [Splits Management](/guides/splits-management) - Configure revenue distribution
* [Royalty Management](/guides/royalty-management) - Upload and process royalty data
* [User Management](/guides/user-management) - Manage collaborators
* [Integrated Workflows](/guides/integrated-workflows) - End-to-end examples

## Support

Need help with financial management?

* **Documentation**: [apidocs.royalti.io](https://apidocs.royalti.io)
* **API Status**: [status.royalti.io](https://status.royalti.io)
* **Support Email**: [support@royalti.io](mailto:support@royalti.io)
* **Developer Community**: [community.royalti.io](https://community.royalti.io)
