Equity Transactions
Equity transactions track ownership changes in company shares. The API uses double-entry bookkeeping: each transaction creates balanced entries where shares move from one party to another (or from/to a void pool for issuances and retirements).
Endpoints
List Transactions
GET /api/v2/equity/transactions
Retrieves a paginated list of equity transactions.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | Filter by client account |
| business_partner_id | integer | No | Filter by shareholder |
| share_class | string | No | Filter by share class (e.g., COMMON, PREFERRED) |
| transaction_type | string | No | Filter by transaction type (e.g., ISSUANCE, TRANSFER) |
| date_from | date | No | Filter transactions from this date |
| date_to | date | No | Filter transactions to this date |
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Items per page (default: 100, max: 100) |
| with | string | No | Include related resources (supported: business_partner, created_by, updated_by) |
Response
{
"data": [
{
"id": 1,
"client_account_id": 7,
"transaction_date": "2024-03-15",
"transaction_type": "ISSUANCE",
"transaction_group_id": "550e8400-e29b-41d4-a716-446655440000",
"business_partner_id": 56,
"share_class": "COMMON",
"quantity": "1000.000000",
"price_per_share": "100.000000",
"notes": "Initial share issuance",
"split_ratio_numerator": null,
"split_ratio_denominator": null,
"created_at": "2024-03-15T10:00:00Z",
"created_by_id": 7,
"updated_at": "2024-03-15T10:00:00Z",
"updated_by_id": null
}
],
"meta": {
"page": 1,
"pages": 1,
"per_page": 100,
"records": 1
}
}
Get Transaction
GET /api/v2/equity/transactions/{id}
Retrieves a specific equity transaction by ID.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| with | string | No | Include related resources (supported: business_partner, created_by, updated_by) |
Response
{
"id": 1,
"client_account_id": 7,
"transaction_date": "2024-03-15",
"transaction_type": "ISSUANCE",
"transaction_group_id": "550e8400-e29b-41d4-a716-446655440000",
"business_partner_id": 56,
"share_class": "COMMON",
"quantity": "1000.000000",
"price_per_share": "100.000000",
"notes": "Initial share issuance",
"split_ratio_numerator": null,
"split_ratio_denominator": null,
"created_at": "2024-03-15T10:00:00Z",
"created_by_id": 7,
"updated_at": "2024-03-15T10:00:00Z",
"updated_by_id": null
}
Issue Shares
POST /api/v2/equity/transactions/issue
Issues new shares to a shareholder.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | The client account ID |
| business_partner_id | integer | Yes | The shareholder receiving shares |
| share_class | string | Yes | Share class (see Share Classes) |
| quantity | decimal | Yes | Number of shares to issue (must be positive) |
| price_per_share | decimal | No | Price per share |
| transaction_date | date | No | Transaction date (defaults to today) |
| notes | string | No | Additional notes |
Example Request
{
"client_account_id": 7,
"business_partner_id": 56,
"share_class": "COMMON",
"quantity": "1000",
"price_per_share": "100",
"transaction_date": "2024-03-15",
"notes": "Series A funding round"
}
Response
Returns the shareholder’s transaction entry with status 201 Created.
Transfer Shares
POST /api/v2/equity/transactions/transfer
Transfers shares between shareholders.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | The client account ID |
| from_business_partner_id | integer | Yes | The shareholder transferring shares |
| to_business_partner_id | integer | Yes | The shareholder receiving shares |
| share_class | string | Yes | Share class being transferred |
| quantity | decimal | Yes | Number of shares to transfer (must be positive) |
| price_per_share | decimal | No | Transfer price per share |
| transaction_date | date | No | Transaction date (defaults to today) |
| notes | string | No | Additional notes |
Example Request
{
"client_account_id": 7,
"from_business_partner_id": 56,
"to_business_partner_id": 57,
"share_class": "COMMON",
"quantity": "500",
"price_per_share": "150",
"transaction_date": "2024-06-01",
"notes": "Secondary sale"
}
Response
Returns the recipient’s transaction entry with status 201 Created.
Buyback Shares
POST /api/v2/equity/transactions/buyback
Company buys back shares from a shareholder. The shares become treasury stock held by the company.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | The client account ID |
| from_business_partner_id | integer | Yes | The shareholder selling shares |
| company_business_partner_id | integer | Yes | The company entity receiving treasury stock |
| share_class | string | Yes | Share class being bought back |
| quantity | decimal | Yes | Number of shares to buy back (must be positive) |
| price_per_share | decimal | No | Buyback price per share |
| transaction_date | date | No | Transaction date (defaults to today) |
| notes | string | No | Additional notes |
Example Request
{
"client_account_id": 7,
"from_business_partner_id": 56,
"company_business_partner_id": 58,
"share_class": "COMMON",
"quantity": "200",
"price_per_share": "120",
"notes": "Share buyback program"
}
Response
Returns the company’s transaction entry with status 201 Created.
Retire Shares
POST /api/v2/equity/transactions/retire
Retires treasury shares, permanently reducing total outstanding shares.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | The client account ID |
| company_business_partner_id | integer | Yes | The company entity holding treasury stock |
| share_class | string | Yes | Share class being retired |
| quantity | decimal | Yes | Number of shares to retire (must be positive) |
| transaction_date | date | No | Transaction date (defaults to today) |
| notes | string | No | Additional notes |
Example Request
{
"client_account_id": 7,
"company_business_partner_id": 58,
"share_class": "COMMON",
"quantity": "100",
"notes": "Treasury share cancellation"
}
Response
Returns the company’s transaction entry with status 201 Created.
Split Shares
POST /api/v2/equity/transactions/split
Performs a stock split or reverse split for a shareholder’s position.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | The client account ID |
| business_partner_id | integer | Yes | The shareholder whose shares are being split |
| share_class | string | Yes | Share class being split |
| old_quantity | decimal | Yes | Current number of shares (must match actual position) |
| new_quantity | decimal | Yes | New number of shares after split |
| transaction_date | date | No | Transaction date (defaults to today) |
| notes | string | No | Additional notes |
Example Request (2-for-1 Split)
{
"client_account_id": 7,
"business_partner_id": 56,
"share_class": "COMMON",
"old_quantity": "1000",
"new_quantity": "2000",
"notes": "2-for-1 stock split"
}
Example Request (Reverse Split 1-for-10)
{
"client_account_id": 7,
"business_partner_id": 56,
"share_class": "COMMON",
"old_quantity": "1000",
"new_quantity": "100",
"notes": "1-for-10 reverse split"
}
Response
Returns the resulting transaction entry with status 201 Created.
Get Positions
GET /api/v2/equity/positions
Retrieves current share positions (holdings) per shareholder and share class.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | Filter by client account |
| business_partner_id | integer | No | Filter by specific shareholder |
| share_class | string | No | Filter by share class |
| include_void | boolean | No | Include void (unissued) shares (default: false) |
Response
{
"positions": [
{
"business_partner_id": 56,
"share_class": "COMMON",
"quantity": "1500.000000",
"cost_basis": "150000.000000"
},
{
"business_partner_id": 57,
"share_class": "COMMON",
"quantity": "500.000000",
"cost_basis": "75000.000000"
}
]
}
Get Cap Table
GET /api/v2/equity/cap-table
Generates a capitalization table showing ownership distribution.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| client_account_id | integer | Yes | The client account ID |
| company_business_partner_id | integer | Yes | The company entity (excluded from shareholder list) |
Response
{
"shareholders": [
{
"business_partner_id": 56,
"name": "Investor A",
"positions": {
"COMMON": {
"shares": "1500.000000",
"percentage": "75.00"
}
},
"total_shares": "1500.000000",
"total_percentage": "75.00"
},
{
"business_partner_id": 57,
"name": "Investor B",
"positions": {
"COMMON": {
"shares": "500.000000",
"percentage": "25.00"
}
},
"total_shares": "500.000000",
"total_percentage": "25.00"
}
],
"share_classes": ["COMMON"],
"total_shares": "2000.000000"
}
Get Share Classes
GET /api/v2/equity/share-classes
Returns available share class types.
Response
{
"share_classes": [
{"value": "COMMON", "label": "COMMON"},
{"value": "PREFERRED", "label": "PREFERRED"},
{"value": "SERIES_A", "label": "SERIES_A"},
{"value": "SERIES_B", "label": "SERIES_B"},
{"value": "SERIES_C", "label": "SERIES_C"},
{"value": "SEED", "label": "SEED"},
{"value": "CONVERTIBLE_NOTE", "label": "CONVERTIBLE_NOTE"},
{"value": "SAFE", "label": "SAFE"}
]
}
Get Transaction Types
GET /api/v2/equity/transaction-types
Returns available transaction types.
Response
{
"transaction_types": [
{"value": "ISSUANCE", "label": "ISSUANCE"},
{"value": "TRANSFER", "label": "TRANSFER"},
{"value": "BUYBACK", "label": "BUYBACK"},
{"value": "RETIREMENT", "label": "RETIREMENT"},
{"value": "SPLIT", "label": "SPLIT"},
{"value": "CONVERSION", "label": "CONVERSION"}
]
}
Share Classes
| Value | Description |
|---|---|
| COMMON | Common/ordinary shares with voting rights |
| PREFERRED | Preferred shares with priority dividends |
| SERIES_A | Series A funding round shares |
| SERIES_B | Series B funding round shares |
| SERIES_C | Series C funding round shares |
| SEED | Seed round shares |
| CONVERTIBLE_NOTE | Convertible note instrument |
| SAFE | Simple Agreement for Future Equity |
Transaction Types
| Value | Description |
|---|---|
| ISSUANCE | New shares issued to a shareholder |
| TRANSFER | Shares transferred between shareholders |
| BUYBACK | Company buys back shares from shareholder |
| RETIREMENT | Company retires treasury stock |
| SPLIT | Stock split or reverse split |
| CONVERSION | Convert shares from one class to another |
Error Responses
| Status Code | Description |
|---|---|
| 400 | Invalid request (missing fields, invalid share class, insufficient shares) |
| 403 | Forbidden (no access to client account) |
| 404 | Transaction not found |
Insufficient Shares Error
When a transfer, buyback, retirement, or split cannot complete due to insufficient shares:
{
"error": "Insufficient shares: shareholder has 500 but 1000 required",
"status": 400
}
Business Rules
- Double-entry bookkeeping: Every transaction creates balanced entries (shares received = shares given)
- Quantity must be positive: All quantity parameters must be greater than zero
- Balance validation: Transfers, buybacks, retirements, and splits validate sufficient shares before proceeding
- Row-level locking: Concurrent transactions are prevented using database locks
- Cost basis tracking: Weighted average cost method is used when shares are sold
- Self-transfer prevention: Cannot transfer or buyback shares to/from the same entity
- Split validation: The
old_quantitymust exactly match the shareholder’s current position
Common Use Cases
- Company formation: Issue initial shares to founders
- Funding rounds: Issue new shares to investors (Series A, B, C)
- Secondary transactions: Transfer shares between existing shareholders
- Employee equity: Issue shares or options to employees
- Share buybacks: Company repurchases shares from shareholders
- Share cancellation: Retire treasury shares to reduce outstanding stock
- Stock splits: Adjust share count while maintaining ownership percentages