Positions
Positions are the edges in Addepar's ownership graph. A position connects two entities: an owner (the entity that holds something) and an owned (the entity being held). Every financial relationship in the system is modeled as a position: a client owns a trust, a trust owns an account, an account holds a stock. Positions are how Addepar knows who owns what, and they are the foundation for every portfolio calculation, performance return, and allocation report.
How positions work
A position answers one question: "Entity A owns something in Entity B." The nature of that ownership depends on the owned entity's ownership type:
| Owned entity's ownership type | What the position tracks | Required attributes at creation |
|---|---|---|
PERCENT_BASED | A percentage of the owned entity (e.g., 60% of a trust) | incepting_open_position_date, incepting_open_position_ownership_percentage |
SHARE_BASED | A number of shares (established by transactions, not set on the position) | None (position is a link; share count comes from transactions) |
VALUE_BASED | A currency amount (established by transactions, not set on the position) | None (position is a link; value comes from transactions) |
This is the critical distinction. For percent-based entities (trusts, accounts, vehicles), the position itself carries the ownership stake. For share-based and value-based entities (stocks, bonds, funds), the position is a link and the actual quantity is determined by the sum of transactions recorded against it.
Multiple positions between the same entities: The system allows more than one open position between the same owner and owned entity (e.g., different lots of the same stock in the same account). The Positions API always reads and writes the incepting open position, which is the original position created between those two entities.
Position lifecycle: A position is "open" from its inception date until closed. For share-based entities, the position closes when transactions reduce the share count to zero. For percent-based entities, the position remains open as long as the ownership percentage is greater than zero.
Overview
| Base route | /v1/positions |
| Produces | JSON |
| Pagination | Yes |
| OAuth scopes | POSITIONS or POSITIONS_WRITE |
Access requirements
- API Access: Create, edit, and delete.
- Portfolio Access: Required to retrieve, update, and delete positions.
- Transaction permission: "Transactions: Full permission (view, create, and edit)" is required to create, update, and delete positions.
- Manage Attributes: Required to apply, edit, or delete attributes on positions.
Resource attributes
| Attribute | Description |
|---|---|
name | String -- Position name. Required for cash positions. Must be unique among cash positions with the same owner/owned pair. Example: "GOOG" |
display_name | String -- User-facing display name for the position. Example: "Google Class A" |
incepting_open_position_date | String -- Date ownership was first established, formatted YYYY-MM-DD. Required for percent-based positions. For accounts that directly own share-based assets, use a date one day before the first transaction. Example: "2015-12-31" |
incepting_open_position_ownership_percentage | Number -- Ownership percentage as a decimal. Required for percent-based positions. 1.0 = 100%. Example: 0.5 |
incepting_open_position_value | Number -- Starting value for value-based positions. Example: 5 |
created_at | String -- Read-only. ISO 8601 timestamp. Example: "2023-07-28T02:24:30Z" |
modified_at | String -- Read-only. ISO 8601 timestamp. Example: "2023-07-30T10:43:21Z" |
Relationships:
| Relationship | Description |
|---|---|
owner | The entity that holds the position (e.g., a client, account, or trust). |
owned | The entity being held (e.g., a stock, fund, or sub-account). |
Custom Addepar Attributes with position_custom_attributes usage can also be applied to positions via PATCH.
Get a position
Returns the specified position with its inception attributes and owner/owned relationships.
GET /v1/positions/:id
curl -X GET "https://{firm}.addepar.com/api/v1/positions/100" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Accept: application/vnd.api+json"
{
"data": {
"id": "100",
"type": "positions",
"attributes": {
"incepting_open_position_date": "2010-01-01",
"incepting_open_position_ownership_percentage": 1.0,
"created_at": "2023-07-28T02:24:30Z",
"modified_at": "2023-07-30T10:43:21Z"
},
"relationships": {
"owner": {
"links": {
"self": "/v1/positions/100/relationships/owner",
"related": "/v1/positions/100/owner"
},
"data": { "type": "entities", "id": "1" }
},
"owned": {
"links": {
"self": "/v1/positions/100/relationships/owned",
"related": "/v1/positions/100/owned"
},
"data": { "type": "entities", "id": "2" }
}
},
"links": { "self": "/v1/positions/100" }
},
"included": []
}
Related entity endpoints:
| Endpoint | Returns |
|---|---|
GET /v1/positions/:id/owner | Full entity details for the owner |
GET /v1/positions/:id/owned | Full entity details for the owned entity |
GET /v1/positions/:id/relationships/owner | Owner entity type and ID only |
GET /v1/positions/:id/relationships/owned | Owned entity type and ID only |
Get all positions
Returns all positions accessible to the authenticated user. Results are paginated.
GET /v1/positions
curl -X GET "https://{firm}.addepar.com/api/v1/positions" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Accept: application/vnd.api+json"
Filter parameters:
| Parameter | Description |
|---|---|
fields[positions] | Return only specified attributes. Pass fields[positions]=[] to omit all attributes (returns only relationships). Example: fields[positions]=incepting_open_position_date |
filter[created_before] | Positions created on or before date. Format: YYYY-MM-DD |
filter[created_after] | Positions created on or after date. Format: YYYY-MM-DD |
filter[modified_before] | Positions modified on or before date. Format: YYYY-MM-DD |
filter[modified_after] | Positions modified on or after date. Format: YYYY-MM-DD |
filter[owner_model_types] | Positions whose owner entity has one of the specified model types. Example: filter[owner_model_types]=PERSON_NODE,TRUST |
filter[owned_model_types] | Positions whose owned entity has one of the specified model types. Example: filter[owned_model_types]=STOCK,BOND |
filter[owner_entity_id] | Positions owned by the specified entity IDs. Example: filter[owner_entity_id]=24,26 |
filter[owned_entity_id] | Positions holding the specified entity IDs. Example: filter[owned_entity_id]=23,25 |
The owner_entity_id and owned_entity_id filters are the most common for integration use. To find all holdings in a specific account: filter[owner_entity_id]=<account_id>. To find all accounts that hold a specific security: filter[owned_entity_id]=<security_id>.
Create positions
Creates one or more positions linking an owner entity to an owned entity.
POST /v1/positions
Share-based or value-based position (account owns a stock):
curl -X POST "https://{firm}.addepar.com/api/v1/positions" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{
"data": {
"type": "positions",
"attributes": {},
"relationships": {
"owner": {
"data": { "type": "entities", "id": "27" }
},
"owned": {
"data": { "type": "entities", "id": "29" }
}
}
}
}'
{
"data": {
"id": "338",
"type": "positions",
"relationships": {
"owner": {
"links": {
"self": "/v1/positions/338/relationships/owner",
"related": "/v1/positions/338/owner"
},
"data": { "type": "entities", "id": "27" }
},
"owned": {
"links": {
"self": "/v1/positions/338/relationships/owned",
"related": "/v1/positions/338/owned"
},
"data": { "type": "entities", "id": "29" }
}
},
"links": { "self": "/v1/positions/338" }
},
"included": []
}
Percent-based position (person owns a trust):
For percent-based owned entities, you must include the inception date and ownership percentage:
curl -X POST "https://{firm}.addepar.com/api/v1/positions" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{
"data": {
"type": "positions",
"attributes": {
"incepting_open_position_date": "2001-01-01",
"incepting_open_position_ownership_percentage": 1.0
},
"relationships": {
"owner": {
"data": { "type": "entities", "id": "22" }
},
"owned": {
"data": { "type": "entities", "id": "23" }
}
}
}
}'
Multiple positions in a single request:
Pass an array in data to create several positions at once. Each element follows the same structure as a single create.
Response codes:
201 Created-- Position created successfully400 Bad Request-- Invalid payload or missing required fields403 Forbidden-- Insufficient permissions or scope not granted404 Not Found-- Owner or owned entity does not exist or is not accessible409 Conflict--typefield must be"positions"
Edit positions
Updates the incepting open position. Only include the attributes you want to change.
PATCH /v1/positions/:id (single) or PATCH /v1/positions (bulk)
curl -X PATCH "https://{firm}.addepar.com/api/v1/positions/104" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{
"data": {
"type": "positions",
"id": "104",
"attributes": {
"incepting_open_position_date": "2010-01-01",
"incepting_open_position_ownership_percentage": 0.2
}
}
}'
You can also apply custom position-level attributes:
curl -X PATCH "https://{firm}.addepar.com/api/v1/positions/998" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{
"data": {
"type": "positions",
"id": "998",
"attributes": {
"_custom_balance_sheet_12345": [
{ "value": "Below The Line" }
],
"display_name": "My Cash Asset"
}
}
}'
Custom attributes on positions use the same time-varying format as entity attributes.
Response codes:
200 OK-- Position updated successfully400 Bad Request-- Invalid payload403 Forbidden-- Insufficient permissions or scope not granted404 Not Found-- Position does not exist or not accessible409 Conflict-- ID mismatch between URL and payload, ortypeis not"positions"
Delete positions
Permanently removes one or more positions. This operation is irreversible. A position cannot be deleted if it has transactions recorded against it. Delete or reassign those transactions first.
DELETE /v1/positions/:id (single) or DELETE /v1/positions (bulk)
curl -X DELETE "https://{firm}.addepar.com/api/v1/positions/100" \
-H "Authorization: Basic {credentials}" \
-H "Addepar-Firm: 1" \
-H "Accept: application/vnd.api+json"
204 No Content
For bulk delete, pass an array of { "type": "positions", "id": "<id>" } objects in the request body.
Response codes:
204 No Content-- Position deleted successfully400 Bad Request-- Position is referenced by transactions and cannot be deleted403 Forbidden-- Insufficient permissions or scope not granted404 Not Found-- Position does not exist or not accessible
Common integration patterns
Building the ownership graph: After creating entities, establish the ownership hierarchy through positions. A typical structure: Person (client) → Trust → Holding Account → Securities. Create positions top-down so that portfolio queries on the Person aggregate all downstream holdings.
Custodian reconciliation: Use filter[owner_entity_id] to retrieve all positions in an account, compare against the custodian feed, and create/close positions to match. For share-based positions, the share count is determined by transactions, so reconciliation usually means posting buy/sell transactions rather than editing the position itself.
Inception date guidance: For percent-based positions, the inception date determines when performance calculations begin. For accounts that directly own share-based assets, set the inception date one day before the first transaction date. If the first transaction is a buy on 2023-01-15, set incepting_open_position_date to 2023-01-14. Using a historical date like 1900-01-01 is valid for hierarchical positions (person owns trust) where the relationship predates your data.
Related
- Entities -- The nodes that positions connect
- Transactions -- Record value changes against positions (buys, sells, contributions)
- Addepar Attributes -- Apply custom metadata to positions
- Portfolio Query -- Aggregate position data across the ownership graph
- Groups -- Organize entities for permission scoping and reporting
Updated 14 days ago