Partner API
Last updated: 17 August 2026
This documentation covers the Alternatives Partner API (v3) — the customer-facing interface for programmatic access to Alternatives’ private-market data across Southeast Asia. It is a read-only REST API that returns JSON and is intended for external API subscribers. Access is subscription-gated — each endpoint is protected by entitlements that are enabled according to your subscription.
v3 replaces v2. If you are migrating from the legacy API at
api.alternatives.pe/api/v2, see the Migration Guide for a full breakdown of what changed.
What the API Covers
| Entity Type | What It Represents | Example |
|---|---|---|
| Capital Receivers | Companies and startups that have raised funding | ShopBack |
| Capital Allocators | Investors (VC firms, family offices, PE funds) that deploy capital | Wavemaker Group |
| Funds | Individual fund vehicles managed by a capital allocator | Wavemaker Pacific 1, Bain Capital Asia III |
| People | Founders, directors, and other individuals linked to companies | Shanru Lai (ShopBack co-founder) |
| Investors | Investment totals for any entity that has been a buyer in a transaction, by base entity type | Any company, person, or shareholder group that has invested |
| Service Providers | Auditors and professional-services firms | Ernst & Young LLP |
| Legal Entities | Underlying registered companies — returned as a nested object on profile detail responses | Any registered business |
| Reference Data | Taxonomies and lookup lists for filter fields | Countries, stages, themes, industries |
New to the API? The Data Model page explains how Profiles relate to the underlying Legal Entity and what each UUID identifies.
Base URL
https://api.altdmp.io/v3/partners/
All endpoints are relative to this base. For example, to list capital receivers:
curl https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
resp = requests.get(f"{BASE}/capital-receivers/", headers=headers)
print(resp.json())
Request Format
Most list endpoints support two calling styles:
GET— query-string filters (search,ordering,limit,offset)POST— JSON body for advanced range queries, multi-value filters, and boolean logic
On POST, the request body accepts only the filters object. Pagination and sorting (search, ordering, limit, offset) are always query parameters — sending them in the body returns 400 Bad Request.
Filtering has its own page. Filtering is the reference — every operator with its exact matching behavior, the accepted body shapes, the supported filter field list for each endpoint, and the cases where a filter is accepted but not applied.
filtersgoes in the body, never on the query string. The two directions are not interchangeable:search,ordering,limit, andoffsetare query parameters only, andfiltersis a body parameter only. A request that puts a value in?filters=returns400 Bad Request— it is not applied, and it is not ignored. A bare?filters=with no value expresses no filter and is accepted. The sole exception is/investors/, which ignores a query-stringfiltersand returns unfiltered results; do not rely on that.
Pagination
All list responses are paginated. Use limit and offset query parameters:
# Page 2 of results (20 per page)
curl "https://api.altdmp.io/v3/partners/capital-receivers/?limit=20&offset=20" \
-H "Authorization: Bearer YOUR_TOKEN"
resp = requests.get(
f"{BASE}/capital-receivers/",
params={"limit": 20, "offset": 20},
headers=headers,
)
Responses include count, next, and previous fields alongside results.
A few non-list responses omit the pagination keys entirely. The cap table endpoints, for example, drop
count/next/previouswhen the company has no cap table on file. Readresultsrather than branching oncount.
Field Types and Nulls
Three conventions run through every response and are worth setting up for once rather than discovering per endpoint.
Every numeric value is a JSON number. Amounts, percentages, multiples, and rates are returned unquoted — 925652927.23, not "925652927.23". This applies to every endpoint and every field: there is no longer any field that returns a number as a quoted string.
This changed on 2026-08-14. Amounts, percentages, and multiples were previously returned as quoted strings. If your integration parses them as strings (
v.replace(...),parseFloat(v)on a value you assume is text, a schema that types them asstring), it will break. See the changelog entry for the full list of affected fields.
Values carry the precision they are stored with, so the number of decimal places varies by field and sometimes between two fields with the same name — 0.1800, 40.0000, and 374.0000000000 are all valid. Read the value, not the digits. Trailing zeros are a fidelity guarantee, not a display instruction; most JSON parsers discard them anyway (JSON.parse("0.1800") gives 0.18), and nothing about how a value should be formatted can be inferred from them.
If you need exact decimal arithmetic — summing money, comparing valuations — parse into a decimal type rather than a float, the same as you would for any other JSON API. Python’s json module accepts parse_float=decimal.Decimal; in JavaScript, parse with a big-decimal library rather than the native number.
The field name tells you the scale of a percentage. For any value expressing a proportion, you never have to guess whether 0.1875 means 18.75% or 0.1875%:
| Name shape | Scale | 18.75% is written | Example fields |
|---|---|---|---|
Bare name — irr | Fraction | 0.1875 | irr |
_pct / _percentage / percentage in the name | Fraction × 100 | 18.75 | irr_pct, percentage_held_absolute, management_fee_percentage, operating_revenue_growth_yoy_pct |
Where both forms exist they are siblings covering the same figure: irr_pct is always exactly irr × 100. Filters and ordering keys use the scale of the field they name — irr_min=0.15 means 15%.
The rule covers proportions only. Two other kinds of value have rate-like or ratio-like names and are neither a fraction nor a percentage, so neither has a _pct sibling:
- Multiples —
dpi,rvpi,net_multiple. Adpiof1.80means 1.8×, not 180%. - Conversion factors — an exchange
rateof1.3450is a multiplier between two currencies. There is no percentage reading of it.
null means unknown, not zero or false. Nullable booleans (is_raising_now, is_open_to_co_investment, the fund classification flags) return null when nothing has been declared — distinct from false. Nullable amounts return null both when the value is unknown and when it is known to net to zero; they are never 0.00. A null never satisfies a numeric comparison, so rows with a null value are excluded from range filters on that field and sort to the end of an ordering on it, in both directions.
Keys and Display Values
Many concepts are returned twice: once as a stable key and once as a human-readable label. Always join, look up, filter, group, and store on the key. Treat the label as presentation only.
| Use the key | Alongside the label |
|---|---|
type_key | type |
profile_type_key | profile_type |
allocation_type_key | allocation_type_name |
allocation_subtype_key | allocation_subtype_name |
allocation_deal_type_key | allocation_deal_type_name |
latest_investment_stage_key | latest_investment_stage_name |
deal_type_key | deal_type_name |
key (inside themes[], techs[], status, trading_status, audit_opinion, and every other {key, name} object) | name |
Keys are contractual: "capital_allocator" stays "capital_allocator". Labels are not — their exact spelling can change while the thing they describe stays the same. A relabelling would silently re-partition anything keyed on the display string, with no error and no version signal to tell you it happened.
A few fields are the key half of a pair that has no separate _key suffix, because the field itself already holds the key: investor_type ("legal_entity", "person", …), iso_alpha3, iso_code, code on industries and SIC codes, and date_founded_precision. Join on those directly.
type_keyis scoped to the object it appears on — there is no single global vocabulary. On a buyer, seller, shareholder, or LP it names a kind of entity ("capital_allocator","person", …). Onlegal_entity.alternate_names[]it names a kind of name ("alt_name_legal_name","alt_name_fka"). The two never mix, but do not build one shared lookup table across both — readtype_keyin the context of the object holding it.
typeandprofile_typewill change what they display. Today they present values like"CapitalAllocatorProfile"and"capitalallocatorprofile"— the same concept, spelled two different ways, and neither reads as a label. A future release will replace both with proper labels such as"Capital Allocator".Neither field is going away, and nor is the display half of any other pair — only the presented string changes.
type_keyandprofile_type_keyare unaffected. If you join on the keys, this change is invisible to you. If you join ontypeorprofile_type, it will break you.
Cap Table Types
Every capital receiver has a captable_source.type field that tells you how its shareholding data was collected. Always check this field before interpreting cap table results — the response shape and available data differ between the two types.
| Type | How it works | What’s available |
|---|---|---|
managed | Cap table is computed from individual transaction records on the platform. Each share issuance, transfer, and sale is tracked. | Full share counts, investment amounts, deal-stage breakdowns. /investors/ endpoint available. |
snapshot | Cap table is sourced from a periodic shareholder-register filing (e.g. an ACRA annual return). Data reflects a point-in-time view. | Share counts and percentage held as of the snapshot date. Investment amounts not available. /investors/ returns HTTP 400. |
Use the captable_is_managed filter on /capital-receivers/ to segment your queries:
# Companies with full transaction-level cap table data
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filters": {"all": [{"op": "eq", "field": "captable_is_managed", "value": true}]}}'
The same captable_source.type field and response structure applies to /capital-allocators/{uuid}/captable/.
Common Use Cases
| Goal | How |
|---|---|
| Company profile, funding history, cap table | GET /capital-receivers/{uuid}/ → /deals/ → /captable/ |
| Current shareholders for a company | GET /capital-receivers/{uuid}/captable/ |
| Total invested per investor with deal-stage breakdown | GET /capital-receivers/{uuid}/investors/ (managed cap table only) |
| Find VC firms active in SEA at Seed stage | POST /capital-allocators/ filtering preferred_allocation_deal_type_key, then compare against each firm’s actual_allocation_deal_types |
| Fund performance, LP list, size history | GET /funds/{uuid}/performance/ + /aum/ + /commitments/ |
| Look up a founder or director by name | GET /people/?role_type_key=person_association_founder&search=Henry+Chan |
| Registration number lookup | GET /capital-receivers/?search=<name> — registration numbers are in the legal_entity object on the detail response |
| Build filter dropdowns in a UI | GET /reference-data/?type=enums |
Data Model
Last updated: 19 August 2026
Before working with any endpoint, it helps to understand two concepts that run through the entire API: the Legal Entity and the Profile. Most of the UUIDs you encounter are one or the other, and knowing which is which tells you what a given ID identifies and which endpoint it drives.
Legal Entity vs. Profile
A Legal Entity is the underlying registered organization — a company as it exists in a corporate registry, identified by its registration number (e.g. a Singapore UEN). It holds the identity and registration facts: legal name, domicile, headquarters, trading status, year founded, and registration numbers.
A Profile is a role-specific view onto an entity. The API exposes several profile types, each with its own endpoint and its own fields:
| Profile Type | Endpoint | Represents |
|---|---|---|
| Capital Receiver | /capital-receivers/{uuid}/ | The entity in its role as a company that has raised funding |
| Capital Allocator | /capital-allocators/{uuid}/ | The entity in its role as an investor deploying capital |
| Fund | /funds/{uuid}/ | An individual fund vehicle managed by a capital allocator |
| Service Provider | /service-providers/{uuid}/ | The entity in its role as an auditor or professional-services firm |
| Person | /people/{uuid}/ | An individual — a founder, director, or other associated person |
The key relationship: a single Legal Entity can back more than one profile. The same registered company may appear as a Capital Receiver (it raised money) and as a Capital Allocator (it also invests) — two distinct profiles, two distinct profile UUIDs, one shared underlying Legal Entity. This is why registration and identity data lives on the nested legal_entity object rather than being duplicated on each profile.
Not every profile is backed by a Legal Entity. A Capital Allocator can instead be backed by a Person (an angel investor, for example). Profiles carry a
profile_typefield of"legalentity"or"person"to indicate which. Fields that resolve through the legal entity — geography, cap table, financials — returnnullfor person-backed profiles. See Capital Allocators.
How Many Profiles Per Root Record
A profile always hangs off a root record — a Legal Entity, or for capital allocators a Person. The root record is the identity; the profile is a role layered on top of it.
The relationship runs in two directions, and only one of them is one-to-one:
| Profile type | Root record | How many per root |
|---|---|---|
| Capital Receiver | Legal Entity | Exactly one |
| Fund | Legal Entity | Exactly one |
| Capital Allocator | Legal Entity or Person | One per preferred allocation type — more than one is normal |
| Service Provider | Legal Entity | Not limited to one |
So a single company can be a Capital Receiver, a Fund, a Service Provider, and several Capital Allocators simultaneously. Each of those profiles has its own UUID, and none of them is the company’s identity — the root UUID is.
Do not assume one capital allocator profile per firm. A firm that allocates both equity and debt has a separate allocator profile, with a separate UUID, for each. Any figure you total per firm — capital deployed, number of investments, dry powder — must be collapsed on the root UUID first, or a multi-strategy firm is counted once per profile. The same applies to service providers, where there is no limit at all.
The Nested Legal Entity Object
Profile detail responses embed the shared identity data under a legal_entity object:
{
"uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity": {
"uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"display_name": "Company Name",
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"trading_status": {"key": "operating", "name": "Operating"},
"year_founded": 2020,
"registration_numbers": [
{
"reg_number": "202012345A",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
]
}
}
Here the top-level uuid is the profile UUID (a capital receiver, in this case) and legal_entity.uuid is the Legal Entity UUID. They are different IDs pointing at different things: the first drives the profile’s own endpoints, the second identifies the registered company shared across any other profiles built on it.
Understanding the UUIDs
The same underlying entity surfaces different UUIDs depending on where you are in the API. This table maps each one to what it identifies and how to use it:
| UUID | Where it appears | Identifies | Use it with |
|---|---|---|---|
Profile uuid | Top level of every list and detail response | The profile (capital receiver, allocator, fund, service provider, or person) | The matching profile endpoint, e.g. /capital-receivers/{uuid}/ |
legal_entity.uuid | Nested inside the legal_entity object on detail responses | The underlying registered company | Reference key — links profiles that share the same legal entity |
legal_entity_uuid | Flat field on investment rows — the /investments/ sub-resource on capital allocators, funds, and people | The underlying registered company (same value as legal_entity.uuid) | Reference key to correlate rows belonging to the same company |
capital_receiver_uuid | Flat field on investment rows and on every batch response row (deals, financials, news, deal share types) | The capital receiver profile | /capital-receivers/{uuid}/ |
uuid beside a type_key | Buyer / seller / shareholder / organization objects | Whatever type_key says — see above | The endpoint for that key |
Telling Which Namespace a UUID Belongs To
Rows that reference some entity without knowing in advance what kind — a deal’s buyer and seller, a cap-table shareholder, a role’s organization, an LP buyer on a commitment — carry a type_key (or profile_type_key) alongside the uuid. That key names the namespace the uuid lives in, and so which endpoint to call:
| Key value | uuid identifies | Use it with |
|---|---|---|
capital_allocator | A capital allocator profile | /capital-allocators/{uuid}/ |
capital_receiver | A capital receiver profile | /capital-receivers/{uuid}/ |
fund | A fund profile | /funds/{uuid}/ |
service_provider | A service provider profile | /service-providers/{uuid}/ |
person | A person | /people/{uuid}/ |
legal_entity | The underlying registered company | Correlation key only — there is no legal-entity endpoint |
shareholder_group | A grouping of shareholders | Correlation key only |
other, alt, null | Nothing — an aggregate or name-only row | Nothing to fetch |
The uuid is the most specific record available, not always the legal entity. The same firm appears as capital_allocator where it has an allocator profile and as legal_entity where it doesn’t. Branch on the key before joining; a join that assumes one namespace silently drops every row in the others.
Each of these fields is paired with a display-only twin (type, profile_type) whose presented string is not stable. Join on the key. See Keys and Display Values.
Which UUID do I pass to an endpoint? Always the profile UUID. Endpoints like
/capital-receivers/{uuid}/,/capital-allocators/{uuid}/, and/funds/{uuid}/expect the profile UUID for their type — for examplecapital_receiver_uuid, notlegal_entity_uuid. Thelegal_entity_uuidis a correlation key: use it to recognize when two rows or two profiles refer to the same registered company. There is no/legal-entities/{uuid}/endpoint.
Counterparty UUIDs Are Not Stable Identifiers
The uuid on a buyer, seller, shareholder, organization, or investor row is resolved per row, at the time you fetch it, to the most specific profile that entity currently has. It is a handle for fetching detail, not an identity. Two behaviors follow from that, and either one will fork an entity-resolution table keyed on it.
The same company resolves differently depending on the role it plays in the row. Where a company is the outside investor, it resolves to its capital allocator profile. Where the same company is the one being invested in, it resolves to its capital receiver profile. One company, two rows, two different UUIDs and two different type_key values — with nothing tying them together in the response.
The UUID changes when a profile is added later. A company with no allocator profile is reported as {"uuid": "<legal entity uuid>", "type_key": "legal_entity"}. Once an allocator profile exists for that company, the same historical transaction starts returning the allocator profile’s UUID with type_key: "capital_allocator". Nothing about the transaction changed, the record was not corrected, and no field in the response indicates the identifier moved.
So do not use these UUIDs as an entity-resolution key. Key your own company or party table on the root UUID — legal_entity.uuid for an organization, the person UUID for an individual — and treat the counterparty uuid as a per-row pointer you re-read on every sync.
Where To Get A Root UUID
| Response | Root UUID |
|---|---|
Profile detail — /capital-receivers/{uuid}/, /capital-allocators/{uuid}/, /funds/{uuid}/, /service-providers/{uuid}/ | Nested legal_entity.uuid |
/investments/ on capital allocators, funds, and people | Flat legal_entity_uuid |
/investors/ — the top-level list | The row uuid already is the root: investor_type is legal_entity, person, or shareholder_group, never a profile |
| Snapshot cap table | shareholder.uuid is the legal entity or person directly — type_key confirms which |
/capital-receivers/{uuid}/investors/, managed cap table, deal buyer / seller, commitment buyer, role organization | None — a profile-resolved uuid only |
For that last row, resolve the root by fetching the profile’s own detail response and reading legal_entity.uuid. That is one request per profile: legal_entity_uuid is a filter field on /service-providers/ alone, so a set of capital receiver, allocator, or fund UUIDs cannot be crosswalked to their root records in bulk. Plan the resolution step into your ingestion rather than assuming a batch lookup exists.
Some rows have no root record at all. Pooled and unnamed holders — an ESOP pool, an “Other Shareholders” aggregate, a
shareholder_group— are not backed by a legal entity or a person, so there is no root UUID to resolve.type_keyisother,alt,shareholder_group, ornullon these; treat them as unresolvable rather than minting a company for them.
Why Two IDs on the Same Row
Investment rows — the /investments/ sub-resource on capital allocators, funds, and people — carry both capital_receiver_uuid and legal_entity_uuid:
{
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity_uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"capital_receiver_name": "Shopback"
}
Use capital_receiver_uuid to navigate to the company’s profile. Use legal_entity_uuid to group or reconcile rows at the registered-company level — for example, to see that two holdings belong to the same legal entity even when they surfaced through different profiles.
This pairing is specific to investment rows. Cap-table rows carry neither: a managed or snapshot cap-table row identifies its holder through the nested shareholder object and nothing else. See Counterparty UUIDs Are Not Stable Identifiers.
Authentication
Last updated: 17 August 2026
Every request to the Partner API must include a Bearer token in the Authorization header.
Obtaining a Token
Exchange your API key for a short-lived access token:
curl -X POST https://api.altdmp.io/v3/token/issue/ \
-H "Content-Type: application/json" \
-d '{"api_key": "YOUR_API_KEY"}'
import requests
resp = requests.post(
"https://api.altdmp.io/v3/token/issue/",
json={"api_key": "YOUR_API_KEY"},
)
token = resp.json()["access_token"]
Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ij...",
"token_duration": 1440,
"expires_at": "2024-11-21T06:29:30.396717Z"
}
The token is valid for 24 hours (token_duration is in minutes).
Contact support@alternatives.pe to obtain your API key.
Using the Token
Include the token in the Authorization header on every request:
curl https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN"
headers = {"Authorization": f"Bearer {token}"}
resp = requests.get(
"https://api.altdmp.io/v3/partners/capital-receivers/",
headers=headers,
)
Subscription and Access Control
Authentication alone is not sufficient. Each endpoint is also protected by entitlements that are enabled according to your subscription. Your organisation must hold the appropriate entitlements for the resources you need to access.
Entitlements are provisioned automatically when your subscription is activated. Different subscription tiers unlock access to different endpoints and data types. See Plans & Access for the full per-endpoint breakdown by plan. Contact support@alternatives.pe to review or upgrade your subscription.
A
403 Forbiddenresponse means your organisation’s subscription does not include access to that endpoint. Contact support to adjust your subscription.
Rate Limits
The Partner API is rate limited to protect service quality for all clients. Requests are limited to 320 requests per rolling 1-minute window. The window is rolling rather than fixed: at any moment, the count is the number of requests made in the preceding 60 seconds, so capacity frees up continuously rather than resetting on a clock boundary.
When you exceed the limit, the API responds with 429 Too Many Requests and a Retry-After header indicating how many seconds to wait before retrying. The response body is a structured JSON error describing the limit that was hit.
To stay within the limit:
- Honor
Retry-After. When you receive a429, wait the number of seconds it specifies before sending the next request, then retry. Do not retry immediately. - Back off on repeated
429s. If retries keep failing, increase the delay between attempts (exponential backoff) rather than retrying at a fixed interval. - Spread out bulk work. Page through large result sets steadily and avoid issuing requests in tight, unthrottled bursts.
Error Responses
Errors are always JSON. Most carry two keys: status_code, repeating the HTTP status of the response, and detail, a human-readable message.
{
"status_code": 404,
"detail": "The requested resource was not found."
}
| Status | detail | Meaning |
|---|---|---|
400 Bad Request | varies — see 400 response bodies | Malformed request — e.g. an unsupported ordering field, a POST body containing keys other than filters (pass limit, offset, and ordering as query parameters), a filters value passed on the query string instead of in the body, or a missing, oversized, or malformed UUID in filter on a batch endpoint |
401 Unauthorized | Authentication credentials are invalid or missing. | Missing, malformed, or expired Bearer token. The message is fixed, so the body does not distinguish a missing token from an expired one — re-issue the token and retry |
403 Forbidden | You do not have permission to perform this action. | Token is valid but your organisation’s subscription does not include access to that endpoint. See Subscription and Access Control |
404 Not Found | The requested resource was not found. | No record matches the UUID in the path, or the record has since been deleted — deleted records are filtered out, so a UUID that resolved earlier can start returning 404 |
404 Not Found | The requested resource was not found on this server. | The URL matched no route at all. The wording is deliberately different from the message above, so a mistyped path is distinguishable from a missing record |
429 Too Many Requests | — | Rate limit exceeded — wait for the period given in the Retry-After header, then retry. See Rate Limits |
500 Internal Server Error | An unexpected error occurred. Please contact support. | Unhandled server error. The cause is logged on our side and never returned in the response |
Every endpoint can return 401, 403, and 500; endpoints that take a UUID in the path can also return 404; endpoints that accept a body or filter parameters can also return 400. These are declared per operation in the OpenAPI schema and the Postman collection.
400 response bodies
Validation errors raised by the API put the message in a list:
{
"status_code": 400,
"detail": [
"Invalid ordering field 'founded'. Valid ordering fields are: created_at, display_name, term_years, updated_at, vintage_year."
]
}
A few endpoint-specific checks return the message as a plain string, without status_code:
{
"detail": "Investor summary is only available for capital receivers with a managed cap table. Use /partners/capital-receivers/{uuid}/captable/ for snapshot-based cap tables."
}
One check keys the message by the parameter at fault instead of using detail — passing filters on the query string rather than in the request body:
{
"filters": "`filters` must be sent in the JSON request body on this endpoint, not as a query-string parameter.",
"status_code": 400
}
When handling errors, take the status from the HTTP response rather than from the body — status_code is present on most error bodies but not all of them. Read detail and accept either a string or a list of strings, and treat its absence as a valid body: a 400 may instead carry the message under the name of the offending parameter.
Very long URLs return a non-JSON 400
The request line — the method, the full path, and the entire query string — is limited to 8190 bytes. A request over that is rejected before the API runs, so it returns 400 Bad Request as HTML, with no detail and no status_code. If you parse every error body as JSON, guard for this.
Long ?search= values and long comma-separated country or UUID lists are what push a URL over the limit. Move bulk conditions into a POST filters body, or split them across pages.
Plans and Access
Last updated: 15 July 2026
Which Partner API endpoints you can call depends on your subscription plan. This page lists every endpoint and shows whether it is included with Atlas or Allocate.
Custom plans are not covered here. The tables below describe our two standard plans. If your organisation is on a plan we’ve tailored to your requirements, your endpoint access is defined by your agreement and may differ from what’s shown here. Contact support@alternatives.pe if you’re unsure which endpoints your subscription includes.
How Access Works
Two things must be true for a request to succeed:
- Partners API access. Programmatic access is a separate add-on to your subscription. When it’s enabled, your organisation can authenticate and call the API.
- Endpoint entitlement. Each endpoint is individually gated by your plan. If your plan doesn’t include an endpoint, calling it returns
403 Forbiddeneven with a valid token — see Authentication → Subscription and Access Control.
What Differs Between Atlas and Allocate
Most endpoints are available on both plans. The differences are:
| Area | Atlas | Allocate |
|---|---|---|
| Funds (all fund endpoints) | ✓ | ✗ |
| Capital Allocator → LP commitments | ✓ | ✗ |
| Capital Receivers → list / search | ✗ | ✓ |
On Atlas, you can retrieve a capital receiver directly by UUID (and all of its sub-resources), but you cannot list or search the capital-receivers collection. On Allocate, the entire Funds resource and the capital-allocator LP commitments endpoint are not included.
Full Endpoint Matrix
✓ = included · ✗ = not included (returns 403 Forbidden)
Capital Receivers
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET / POST | /v3/partners/capital-receivers/ | ✗ | ✓ |
GET | /v3/partners/capital-receivers/{uuid}/ | ✓ | ✓ |
GET | /v3/partners/capital-receivers/{uuid}/financials/ | ✓ | ✓ |
POST | /v3/partners/capital-receivers/financials/ | ✓ | ✓ |
GET | /v3/partners/capital-receivers/{uuid}/captable/ | ✓ | ✓ |
GET | /v3/partners/capital-receivers/{uuid}/investors/ | ✓ | ✓ |
GET / POST | /v3/partners/capital-receivers/{uuid}/deals/ | ✓ | ✓ |
POST | /v3/partners/capital-receivers/deals/ | ✓ | ✓ |
POST | /v3/partners/capital-receivers/deal-share-types/ | ✓ | ✓ |
GET | /v3/partners/capital-receivers/{uuid}/news/ | ✓ | ✓ |
Capital Allocators
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET / POST | /v3/partners/capital-allocators/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/investments/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/aum/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/commitments/ | ✓ | ✗ |
GET | /v3/partners/capital-allocators/{uuid}/financials/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/captable/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/funds/ | ✓ | ✓ |
GET | /v3/partners/capital-allocators/{uuid}/news/ | ✓ | ✓ |
Funds
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET / POST | /v3/partners/funds/ | ✓ | ✗ |
GET | /v3/partners/funds/{uuid}/ | ✓ | ✗ |
GET | /v3/partners/funds/{uuid}/performance/ | ✓ | ✗ |
GET | /v3/partners/funds/{uuid}/aum/ | ✓ | ✗ |
GET | /v3/partners/funds/{uuid}/commitments/ | ✓ | ✗ |
GET | /v3/partners/funds/{uuid}/investments/ | ✓ | ✗ |
GET | /v3/partners/funds/{uuid}/news/ | ✓ | ✗ |
Investors
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET / POST | /v3/partners/investors/ | ✓ | ✓ |
People
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET / POST | /v3/partners/people/ | ✓ | ✓ |
GET | /v3/partners/people/{uuid}/ | ✓ | ✓ |
GET | /v3/partners/people/{uuid}/roles/ | ✓ | ✓ |
POST | /v3/partners/people/roles/ | ✓ | ✓ |
GET | /v3/partners/people/{uuid}/investments/ | ✓ | ✓ |
GET | /v3/partners/people/{uuid}/news/ | ✓ | ✓ |
Service Providers
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET / POST | /v3/partners/service-providers/ | ✓ | ✓ |
GET | /v3/partners/service-providers/{uuid}/ | ✓ | ✓ |
Reference Data
| Method | Endpoint | Atlas | Allocate |
|---|---|---|---|
GET | /v3/partners/reference-data/ | ✓ | ✓ |
Handling 403 Forbidden
A 403 on an endpoint listed above as ✗ for your plan is expected — it means your subscription doesn’t include that endpoint. To add access, contact support@alternatives.pe to upgrade your plan or arrange a custom plan.
Migrating from v2 to v3
Last updated: 20 August 2026
The v3 Partner API is a complete redesign of the legacy VentureCap v2 API. It is not a wire-compatible upgrade — it is a new contract. This guide covers everything you need to update your integration.
What Changed at a Glance
| Area | v2 | v3 |
|---|---|---|
| Base URL | https://api.alternatives.pe/api/v2/ | https://api.altdmp.io/v3/partners/ |
| Authentication | OAuth2 client credentials → /api/v2/oauth/token | API key → POST /v3/token/issue/ (via PropelAuth) |
| Identifiers | Integer IDs ("id": 1234) | UUIDs ("uuid": "c16a0ffd-…") |
| Pagination envelope | {"data": {"data": [...], "total_records": N, ...}} | {"count": N, "next": "…", "previous": "…", "results": [...]} |
| Max page size | 100 | 1000 (default 20) |
| Ordering | order_by + order_direction | Single ordering param with - prefix for descending |
| Filtering | Query-string only | Query-string and JSON body (POST) |
| Companies | /api/v2/companies/ | /v3/partners/capital-receivers/ |
| Investors | /api/v2/investors/ | /v3/partners/capital-allocators/ + /v3/partners/investors/ |
| Funds | /api/v2/funds/ | /v3/partners/funds/ |
| People | /api/v2/directors/, /api/v2/founders/ | /v3/partners/people/ (unified) |
| Auditors | /api/v2/auditors/ | /v3/partners/service-providers/?service_type=service_provider_type_audit |
| Classification | Sector / theme driven | Five dimensions: themes, techs, business_models, industries, horizontals |
| Money fields | Mixed currency for fund performance fields; company financials already USD | USD-normalized, _usd suffix (explicit in field names for both) |
Breaking Semantic Changes
These are not syntactic renames — they change meaning and require deliberate handling:
- Investors split by allocation type. An investor with both equity and debt allocations now appears as two separate records in API responses — one per allocation type.
- Sectors deprecated.
v3.industriesis a different classification system, not a rename ofv2.sectors. Do not treat industry codes as mapped equivalents of sector IDs. - Theme taxonomy reworked.
v3.themesare not 1:1 withv2.themes. Treat the five-dimension classification as a new framework to adopt explicitly. date_incorporatedmaps todate_founded. The nestedlegal_entityexposesdate_founded(full ISO date) with adate_founded_precisionflag ("year"/"month"/"day"), plus a year-onlyyear_foundedfor convenience.nameis nested.v2.namemaps tov3.legal_entity.display_name, not a top-level field.headquatersspelling fixed. v2 had a typo; v3 usesheadquarters.
Authentication
v2
curl -X POST https://api.alternatives.pe/api/v2/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=YOUR_ID&client_secret=YOUR_SECRET"
Returns {"token": "..."}. Use as a Bearer token.
v3
v3 credentials are issued through PropelAuth. Contact support@alternatives.pe to provision an API key, then exchange it for a short-lived bearer token:
curl -X POST https://api.altdmp.io/v3/token/issue/ \
-H "Content-Type: application/json" \
-d '{"api_key": "YOUR_API_KEY"}'
import requests
token = requests.post(
"https://api.altdmp.io/v3/token/issue/",
json={"api_key": "YOUR_API_KEY"},
).json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
The token is valid for 24 hours. Request new credentials before starting your migration.
Identifiers
v2 used integer IDs throughout. v3 uses UUIDs everywhere — no internal integer IDs are exposed.
# v2
GET /api/v2/companies/4821/
# v3
GET /v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/
# v3 — store uuid from list results for later detail calls
results = requests.get(f"{BASE}/capital-receivers/?search=shopback", headers=headers).json()
uuid = results["results"][0]["uuid"]
detail = requests.get(f"{BASE}/capital-receivers/{uuid}/", headers=headers).json()
There is no mapping endpoint between v2 integer IDs and v3 UUIDs. Re-query by name or registration number to find the corresponding v3 UUID.
Pagination
v2 used a custom doubly-nested envelope:
{
"data": {
"total_records": 1000,
"no_of_pages": 10,
"limit": 100,
"offset": 0,
"data": [{ "id": 1234, "name": "Example Co" }]
}
}
v3 uses a standard limit/offset envelope:
{
"count": 1000,
"next": "https://api.altdmp.io/v3/partners/capital-receivers/?limit=100&offset=100",
"previous": null,
"results": [
{
"uuid": "a1b2c3d4-0000-0000-0000-000000000001",
"legal_entity": {"uuid": "b2c3d4e5-0000-0000-0000-000000000002", "display_name": "Example Co"}
}
]
}
# v2
GET /api/v2/companies/?page=2&page_size=20
# v3
GET /v3/partners/capital-receivers/?limit=20&offset=20
Ordering
# v2
GET /api/v2/companies/?order_by=name&order_direction=desc
# v3 (prefix field with - for descending)
GET /v3/partners/capital-receivers/?ordering=display_name
GET /v3/partners/capital-receivers/?ordering=-last_updated_at
Each endpoint accepts a fixed set of sortable fields. An unsupported ordering value now returns 400 Bad Request with the list of valid fields, rather than being silently ignored.
Filtering Changes
v2 supported query-string filters only. v3 adds a JSON body filter via POST for complex conditions. Simple filters (search, ordering, registration_number) are still supported as query parameters.
The
POSTbody accepts only thefiltersobject.search,ordering,limit, andoffsetare always query parameters — sending them in the body returns400 Bad Request.
There is no
?filters=query parameter. Coming from v2 it is a natural guess, and it returns400 Bad Request. The advanced filter tree is a body parameter only. This is also the practical reason to move bulk conditions into the body: a long filter tree in the query string can push the URL past the 8190-byte request-line limit, which fails before the API runs and returns HTML rather than JSON.
# v2
GET /api/v2/companies?countries=SGP,THA§ors=22,44&themes=35
# v3 — advanced filter via POST body (pagination and sorting go on the query string)
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/?search=platform&ordering=-latest_valuation_usd&limit=100" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"},
{"op": "in", "field": "themes_keys", "value": ["themes_payments", "themes_climate_green_clean"]},
{"op": "gte", "field": "latest_valuation_usd", "value": 10000000}
]
}
}'
Keys vs. display values
v2 mostly returned a single string per concept. v3 returns two: a stable key and a human-readable label. Build every join, lookup, filter, and grouping on the key — type_key, profile_type_key, allocation_type_key, allocation_deal_type_key, investor_type, and the key inside any {key, name} object. The label half (type, profile_type, *_name) is presentation only, and its spelling can change without the underlying thing changing. See Keys and Display Values.
If you are porting v2 code that keyed off display strings such as sector or theme names, this is the change to make while you are in there.
Filter Operators
| Category | Operators |
|---|---|
| Equality | eq, ne |
| Set membership | in, nin |
| String | contains, ncontains, startswith, endswith |
| Numeric / date | gt, gte, lt, lte, range |
| Null | isnull, notnull |
| Logical | all (AND), any (OR), not (NOT) |
range takes a list of exactly two values, low then high — {"op": "range", "field": "date_founded", "value": ["2015-01-01", "2020-12-31"]}. Any other number of values returns 400 Bad Request.
filters must be a JSON object. A list or a scalar — {"filters": ["any"]} — returns 400 Bad Request rather than applying no filter. Omitting filters, or sending null or {}, is the way to ask for an unfiltered list.
Every filter body must start with a logical operator. filters takes all, any, or not at its top level — a bare condition such as {"filters": {"op": "eq", "field": "…", "value": …}} returns 400 Bad Request. Wrap even a single condition:
{"filters": {"all": [{"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"}]}}
all and any take an array of conditions. not takes a single condition object:
{"filters": {"not": {"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"}}}
An array under not is also accepted and is negated as a whole — equivalent to wrapping it in all and negating that.
not needs something to negate. An empty negation — {"not": []}, {"not": {}}, or {"not": {"all": []}} — returns 400 Bad Request. There is no useful reading of “exclude nothing in particular”, and the alternative is a body that asks to exclude rows and returns every one of them. An empty all or any is different: it means you supplied no conditions, so it stays a permissive no-op and returns the unfiltered list.
Conditions nest — an entry inside all or any may itself be another all / any / not block.
A malformed condition anywhere in the body returns 400 Bad Request with a message describing the problem — a non-object where a condition was expected, or a range without exactly two values. This holds in both the nested form ({"all": ["oops"]}) and the flat, field-keyed form ({"name": {"all": ["oops"]}}).
Derived filter fields on capital receivers
POST /v3/partners/capital-receivers/ filters on the fields returned in the response and also on a set of derived ones: financials_latest_financial_year_end, latest_investment_stage_name, latest_investment_stage_key, latest_operating_revenue_usd, operating_revenue_growth_yoy_pct, latest_valuation_usd, and total_funding_usd. Each is computed only when it appears in the filter body or in ordering, so plain list and search requests are unaffected. Filter, ordering, and response all use the same field names.
Geography filters on capital allocators and funds
POST /v3/partners/capital-allocators/ and POST /v3/partners/funds/ both support geography filters via domicile_country_name, domicile_country_iso_alpha3, headquarters_country_name, and headquarters_country_iso_alpha3. For capital allocators, geography comes from the linked legal entity — allocators backed by a Person rather than a legal entity return null and are excluded when a country filter is applied.
Filter migration — capital receivers
| v2 query param | v3 equivalent |
|---|---|
query | search query param |
countries | POST headquarters_country_iso_alpha3 or domicile_country_iso_alpha3 |
sectors | Deprecated — industries_codes is available but uses a different classification |
themes | POST themes_names or themes_keys (taxonomy overhauled) |
investment_stage | POST latest_investment_stage_name or latest_investment_stage_key |
valuation_min / valuation_max | POST latest_valuation_usd with gte / lte |
revenue_min / revenue_max | POST latest_operating_revenue_usd with gte / lte |
revenue_growth_min / revenue_growth_max | POST operating_revenue_growth_yoy_pct with gte / lte |
total_funding_min / total_funding_max | total_funding_min / total_funding_max query params, or POST total_funding_usd with gte / lte |
status | POST trading_status_name |
female_founder | POST is_female_founder |
iso_code | POST domicile_country_iso_alpha3 |
order_by + order_direction | ordering (single param, - prefix for desc) |
Classification Framework
v3 replaces v2’s sector/theme model with a five-dimension classification. Do not treat any v2 dimension as a direct equivalent:
| Dimension | Description |
|---|---|
themes | Thematic groupings (e.g., FinTech, AI, ClimateTech). Taxonomy was overhauled — not 1:1 with v2 themes. |
techs | Underlying technology focus. |
business_models | How the business makes money (Marketplace, SaaS, etc.). |
industries | Different classification system from v2 sectors. Uses string codes ("08", "10") instead of integer IDs. |
horizontals | Cross-cutting capability (Customer Stack, Infra Stack, etc.). |
v2:
{ "sectors": [{"id": 22, "name": "Financial Services"}] }
v3:
{
"industries": [{"code": "10", "description": "Financial and Insurance Activities"}],
"themes": [{"key": "themes_digital_neo_banking", "name": "Digital / Neo Banking"}],
"techs": [{"key": "techs_fintech", "name": "FinTech"}]
}
USD Normalization
v3 normalizes all monetary fields to USD using a deterministic FX policy. Fields are suffixed _usd (e.g., total_funding_usd, latest_valuation_usd, committed_capital_usd). Stop applying FX rates client-side once you migrate.
Response Structure: Nested Legal Entity
v3 wraps registration and identity data under a legal_entity object:
{
"uuid": "...",
"legal_entity": {
"uuid": "...",
"display_name": "Company Name",
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"headquarters": {
"country_name": "Singapore",
"country_iso_alpha3": "SGP",
"state_name": "Central Singapore",
"city_name": "Singapore"
},
"trading_status": {"key": "operating", "name": "Operating"},
"year_founded": 2020,
"registration_numbers": [
{
"reg_number": "202012345A",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
]
},
"themes": [{"key": "themes_payments", "name": "Payments"}],
"industries": [{"code": "10", "description": "Financial and Insurance Activities"}]
}
v2 flat fields mapped to v3 nested equivalents:
# v2 flat field
"uen": "201411189G"
# v3 nested
"legal_entity": {
"registration_numbers": [
{
"reg_number": "201411189G",
"authority_name": "Accounting and Corporate Regulatory Authority",
"authority_type": "UEN"
}
]
}
Endpoint Mapping
Companies → Capital Receivers
| v2 Endpoint | v3 Equivalent | Notes |
|---|---|---|
GET /api/v2/companies/ | GET /v3/partners/capital-receivers/ | List / search |
| — | POST /v3/partners/capital-receivers/ | Advanced JSON filtering |
GET /api/v2/companies/{id}/ | GET /v3/partners/capital-receivers/{uuid}/ | Use UUID, not integer ID |
GET /api/v2/companies/{uen}/uen | GET /v3/partners/capital-receivers/?registration_number={uen} | UEN lookup via query param |
GET /api/v2/companies/{id}/financials | Multiple v3 endpoints | See Company Financials below |
GET /api/v2/companies/{id}/shareholders/ | GET /v3/partners/capital-receivers/{uuid}/investors/ | — |
GET /api/v2/companies/{id}/deals/ | GET /v3/partners/capital-receivers/{uuid}/deals/ | — |
Company Financials
The v2 monolithic /companies/{id}/financials splits across multiple v3 endpoints:
| v2 source | v3 equivalent |
|---|---|
| Basic funding block | GET /v3/partners/capital-receivers/{uuid}/ (detail — funding object) |
| Funding rounds | GET /v3/partners/capital-receivers/{uuid}/deals/ |
| Shareholders | GET /v3/partners/capital-receivers/{uuid}/investors/ |
| Cap table | GET /v3/partners/capital-receivers/{uuid}/captable/ |
| Multi-year financials | GET /v3/partners/capital-receivers/{uuid}/ (financials[] array on detail) |
Capital Providers → Capital Allocators
| v2 Endpoint | v3 Equivalent |
|---|---|
GET /api/v2/investors/ | GET /v3/partners/capital-allocators/ |
GET /api/v2/investors/{id}/ | GET /v3/partners/capital-allocators/{uuid}/ |
GET /api/v2/investors/{id}/portfolio/ | GET /v3/partners/capital-allocators/{uuid}/investments/ |
GET /api/v2/investors/{id}/commitments/ | GET /v3/partners/capital-allocators/{uuid}/commitments/ |
Funds
| v2 Endpoint | v3 Equivalent |
|---|---|
GET /api/v2/funds/ | GET /v3/partners/funds/ |
GET /api/v2/funds/{id}/ | GET /v3/partners/funds/{uuid}/ |
GET /api/v2/funds/{id}/performance/ | GET /v3/partners/funds/{uuid}/performance/ |
GET /api/v2/funds/{id}/lps/ | GET /v3/partners/funds/{uuid}/commitments/ |
GET /api/v2/fund-performances/?fund_id={id} | GET /v3/partners/funds/{uuid}/performance/ |
GET /api/v2/commitment-deals/?fund_id={id} | GET /v3/partners/funds/{uuid}/commitments/ |
GET /api/v2/commitment-deals/?limited_partner_id={id} | GET /v3/partners/capital-allocators/{uuid}/commitments/ |
People
v2 had separate /directors/ and /founders/ endpoints. v3 unifies them under /people/ with a role_type_key filter:
| v2 Endpoint | v3 Equivalent |
|---|---|
GET /api/v2/directors/ | GET /v3/partners/people/?role_type_key=person_association_director |
GET /api/v2/founders/ | GET /v3/partners/people/?role_type_key=person_association_founder |
GET /api/v2/directors/{id}/ | GET /v3/partners/people/{uuid}/ |
GET /api/v2/founders/{id}/ | GET /v3/partners/people/{uuid}/ |
GET /api/v2/people/?first_name=X | GET /v3/partners/people/?search=X |
Auditors → Service Providers
| v2 Endpoint | v3 Equivalent |
|---|---|
GET /api/v2/auditors/ | GET /v3/partners/service-providers/?service_type=service_provider_type_audit |
GET /api/v2/auditors/{id}/ | GET /v3/partners/service-providers/{uuid}/ |
New in v3 (No v2 Equivalent)
| Endpoint | What It Provides |
|---|---|
GET /v3/partners/investors/ | Cross-entity investor discovery (capital allocators, legal entities, persons, shareholder groups) |
GET /v3/partners/service-providers/ | Professional-services firms (auditors, law firms, etc.) |
GET /v3/partners/reference-data/ | Enums, countries, cities, industries, SIC codes |
GET /v3/partners/capital-allocators/{uuid}/aum/ | Allocator AUM time series |
GET /v3/partners/capital-allocators/{uuid}/investments/ | Per-allocator portfolio with share-level data |
GET /v3/partners/capital-allocators/{uuid}/funds/ | Fund profiles managed by an allocator |
GET /v3/partners/capital-allocators/{uuid}/captable/ | Cap table for allocator’s legal entity |
GET /v3/partners/capital-allocators/{uuid}/news/ | News linked to a capital allocator |
GET /v3/partners/funds/{uuid}/aum/ | Fund AUM / size history |
GET /v3/partners/funds/{uuid}/investments/ | Per-fund investments with share-level data |
GET /v3/partners/funds/{uuid}/news/ | News linked to a fund |
GET /v3/partners/people/{uuid}/roles/ | Person-to-organization role associations |
GET /v3/partners/people/{uuid}/investments/ | Per-person portfolio |
GET /v3/partners/people/{uuid}/news/ | News linked to a person |
GET /v3/partners/capital-receivers/{uuid}/news/ | News linked to a capital receiver |
Key Field Mappings
Companies → Capital Receivers
| v2 Field | v3 Field | Notes |
|---|---|---|
id | uuid | Changed to UUID |
name | legal_entity.display_name | Nested |
uen | legal_entity.registration_numbers[].reg_number | Nested; each item includes authority_type and authority_name |
description | legal_entity.description | Nested |
url / website | legal_entity.website_url | Renamed |
database | legal_entity.domicile_country.iso_alpha3 | Renamed to domicile |
headquaters | legal_entity.headquarters.country_iso_alpha3 | Spelling fixed; nested object |
date_incorporated | legal_entity.date_founded | Full date, with date_founded_precision; year_founded also available |
investment_stage | funding.latest_investment_stage_name | Derived from most recent active deal |
total_equity_funding | funding.reported_and_filed_equity_usd | Detail only; USD. Total equity is also broken out into filed_equity_usd / reported_equity_usd; funding.total_funding_usd adds debt |
last_valuation | funding.latest_valuation_usd | Available on list and detail; v2 values were already USD at import — v3 makes it explicit |
size_of_last_round | funding.latest_investment_amount | Detail only |
date_of_last_round | funding.latest_investment_date | — |
revenue | latest_financials.operating_revenue_usd | Latest snapshot on list; historical array on detail; v2 values were already USD at import — v3 makes it explicit |
financial_year_end | latest_financials.financial_year_end | — |
revenue_growth | latest_financials.operating_revenue_growth_yoy_pct | YoY percentage |
ebit | latest_financials.earnings_before_tax_usd | Renamed; v2 values were already USD at import — v3 makes it explicit |
liabilities | latest_financials.liabilities_usd | v2 values were already USD at import — v3 makes it explicit |
status | legal_entity.trading_status.name | v3 trading status enum; do not preserve v2 semantics |
company_raising | is_raising_now | Boolean (was nullable) |
female_founder | legal_entity.is_female_founder | Boolean (was 0/1) |
sectors | (deprecated) | Do not treat industries as a direct replacement |
themes | themes[] | Taxonomy overhauled; {"key": "themes_payments", "name": "Payments"} — match on key, not name. Note “FinTech” is now a tech, not a theme — it appears in techs[] as {"key": "techs_fintech", "name": "FinTech"} |
updated_at | last_updated_at | ISO datetime in v3 |
exit_type, liquidation, liquidation_details | (deprecated) | Use funding_status + transaction flags |
| (n/a) | financial_statements_audited[] | New in v3, detail only: audited financial statements for the company’s underlying legal entity — year, date_of_file, and a signed url that expires one hour after the response. See the detail-only fields |
| (n/a) | financial_statements_extracted[] | New in v3, detail only: machine-extracted statements, same shape as audited |
Capital Providers → Capital Allocators
| v2 Field | v3 Field | Notes |
|---|---|---|
investor_id | uuid | |
name | display_name | |
type | types[].name | |
country | legal_entity.domicile_country.name | |
aum | latest_aum.aum_value_usd | |
stages | preferred_allocation_deal_types[].name |
Fund Performance
| v2 Field | v3 Field | Notes |
|---|---|---|
irr | irr | v3 irr is a fraction — 0.1800 means 18%. v3 also returns irr_pct (18.00) if you want the percentage without multiplying. Check the scale of whatever your v2 code assumed before porting |
tvpi | tvpi | Total Value to Paid-In |
dpi | dpi | Distributions to Paid-In |
rvpi | rvpi | Residual Value to Paid-In |
net_irr | net_irr | |
gross_irr | gross_irr | |
as_of_date | as_of_date | Performance date |
currency | currency.iso_code | v2 currency described the as-reported currency (mixed per record); v3 monetary fields (profit_usd, drawdowns_usd, committed_capital_usd) are always USD-normalized — this is a real semantic change, not just a rename |
provenance | provenance.name | Data source |
Commitment Deals
| v2 Field | v3 Field | Notes |
|---|---|---|
id | uuid | Changed to UUID |
fund_id | Parent URL | Use /funds/{uuid}/commitments/ |
fund_name | Parent resource | Get from fund detail |
lp_id | Different endpoint | Use /capital-allocators/{uuid}/commitments/ |
lp_name | Via allocator detail | |
commitment_amount | investment_amount_usd | |
commitment_date | date | |
vintage | fund.vintage_year | From fund |
currency | transaction_currency.iso_code | |
provenance | provenance.name |
Method Matrix
Complete endpoint reference for the v3 Partner API surface.
Capital Receivers
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/capital-receivers/ | List | search, ordering, registration_number, limit, offset |
POST | /v3/partners/capital-receivers/ | Filter | JSON filters, search, ordering, limit, offset |
GET | /v3/partners/capital-receivers/{uuid}/ | Detail | — |
GET | /v3/partners/capital-receivers/{uuid}/financials/ | Detailed financials | limit, offset |
GET | /v3/partners/capital-receivers/{uuid}/investors/ | Investors in this entity | limit, offset |
GET | /v3/partners/capital-receivers/{uuid}/deals/ | Funding rounds + transactions | search, ordering, limit, offset |
POST | /v3/partners/capital-receivers/{uuid}/deals/ | Filter funding rounds | JSON filters, search, ordering, limit, offset |
GET | /v3/partners/capital-receivers/{uuid}/news/ | News articles | ordering, limit, offset |
Capital Allocators
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/capital-allocators/ | List | search, ordering, limit, offset |
POST | /v3/partners/capital-allocators/ | Filter | JSON filters, search, ordering, limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/ | Detail | — |
GET | /v3/partners/capital-allocators/{uuid}/commitments/ | Commitments by allocator | ordering, limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/aum/ | Allocator AUM history | ordering, limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/investments/ | Investments by allocator | limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/financials/ | Historical financial statements | limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/captable/ | Cap table for allocator’s legal entity | limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/funds/ | Fund profiles managed by allocator | limit, offset |
GET | /v3/partners/capital-allocators/{uuid}/news/ | News articles | ordering, limit, offset |
Funds
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/funds/ | List | search, ordering, limit, offset |
POST | /v3/partners/funds/ | Filter | JSON filters, search, ordering, limit, offset |
GET | /v3/partners/funds/{uuid}/ | Detail | — |
GET | /v3/partners/funds/{uuid}/performance/ | Performance history | ordering, limit, offset |
GET | /v3/partners/funds/{uuid}/aum/ | AUM / size history | ordering, limit, offset |
GET | /v3/partners/funds/{uuid}/commitments/ | Commitments to fund | ordering, limit, offset |
GET | /v3/partners/funds/{uuid}/investments/ | Investments by fund | limit, offset |
GET | /v3/partners/funds/{uuid}/news/ | News articles | ordering, limit, offset |
People
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/people/ | List | search, role_type_key, role_type_name, ordering, limit, offset |
POST | /v3/partners/people/ | Filter | JSON filters, search, role_type_key, role_type_name, ordering, limit, offset |
GET | /v3/partners/people/{uuid}/ | Detail | — |
GET | /v3/partners/people/{uuid}/roles/ | Org roles | role_type_key, role_type_name, limit, offset |
GET | /v3/partners/people/{uuid}/investments/ | Investments by person | limit, offset |
GET | /v3/partners/people/{uuid}/news/ | News articles | ordering, limit, offset |
Investors
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/investors/ | Discover investors | investor_type, search, invested_in_stage, invested_on_from, invested_on_to, ordering, limit, offset |
POST | /v3/partners/investors/ | Filter discovery | JSON filters with investor_type and/or name/search, plus pagination |
Service Providers
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/service-providers/ | List | service_type, search, ordering, limit, offset |
POST | /v3/partners/service-providers/ | Filter | JSON filters, service_type, search, ordering, limit, offset |
GET | /v3/partners/service-providers/{uuid}/ | Detail | — |
Reference Data
| Method | Endpoint | Purpose | Key params / body |
|---|---|---|---|
GET | /v3/partners/reference-data/ | Enums, countries, cities, industries, SIC codes | type, enum_categories |
Coverage Gap Summary
v2 fields, filters, and endpoints that have no direct v3 equivalent.
Fields Not in v3
| Category | v2 field(s) | Severity | Workaround |
|---|---|---|---|
| Companies | additional_ids | Low | Not migrated. |
| Companies | size_of_last_round, date_of_last_round | Medium | Available on CR detail as funding.latest_investment_amount and funding.latest_investment_date. |
| Companies | date_incorporated (full date) | Low | Available in v3 as legal_entity.date_founded (with date_founded_precision); year_founded also retained. |
| Companies | liquidation_details | Low | Deprecated; no v3 replacement. |
| Company Financials | fundings[] pre-money valuation | Medium | Per-round detail available via /capital-receivers/{uuid}/deals/. pre_money_valuation is not exposed. |
| Company Financials | additional_fundings[] (news-sourced rounds) | Medium | Not in Partner API. |
| Company Financials | revenue[] multi-year history | Medium | CR detail has a condensed financials[]. For the full statement history use /capital-receivers/{uuid}/financials/. |
| Company Financials | shareholders[].value_of_investment_at_last_round_valuation | Medium | Not in Partner API. |
| Company Financials | per_share_class_summary[] (raw share_class_id) | Low | Largely covered by deals[].transactions[]. Raw integer share_class_id is unavailable. |
| Investors | investor_uen on list | Low | Use /capital-receivers/{uuid}/investors/ registration_numbers[].reg_number. |
| Investors | investment_date on list | Low | Use first_investment_date / latest_investment_date on /capital-receivers/{uuid}/investors/. |
| Investors | Per-company stage amounts on /investments/ | Medium | Only on investor list as investments_by_deal_type; not per-company on /investments/. |
| Investors | Valuation calculations (value_of_investment_at_last_round_valuation*) | Medium | Not in Partner API. |
| Investors | Share-class amounts (amount_invested_ordinary, _preference) | Low | Not in Partner API. |
| Investors | max_price_per_share | Low | Not in Partner API. |
| Fund list | Inline performance metrics (irr, dpi, rvpi, net_multiple) | Medium | Separate call to /funds/{uuid}/performance/. |
| Fund list | size on list | Medium | Separate call to /funds/{uuid}/aum/. |
| Fund Performance | source_name, capital_provider_source_acting_as | Low | Not exposed. |
| Fund Performance | report_path, reporting_period | Low | Use year + quarter; report path is internal. |
| Commitment Deals | size (deal size) | Low | Not in Partner API. |
Filters Not in v3
| Category | v2 filter(s) | Workaround |
|---|---|---|
| Companies | total_funding_min/max (server-side aggregate) | Not available as a server-side filter. |
| Investors | sectors, themes, invested_in_stage, invested_on_from/to | Not available in Partner API; filter client-side or via other endpoints. |
| Investors | order_by + order_direction | Not available; no server-side ordering on investor results. |
| Funds | net_irr_min/max, net_multiple_min/max, dpi_min/max, rvpi_min/max | Not available; performance is separate from fund list. |
| Funds | last_report_quarter | Not available. |
| Commitment Deals | fund_type, query | Filter funds first, then query per-fund commitments. |
v2 Endpoints Fully Deprecated
| v2 endpoint | Reason / replacement |
|---|---|
GET /api/v2/companies/{uen}/uen/financials | Use ?registration_number= + detail + /financials/. |
GET /api/v2/fund-performances/ (standalone list) | Performance is per-fund only via /funds/{uuid}/performance/. |
GET /api/v2/commitment-deals/ (standalone list) | Commitments are per-fund or per-allocator only. |
GET /api/v2/commitment-deals/{dealId} (direct detail) | Match by UUID in nested results. |
Worked Examples
Authenticate and list capital receivers
# 1. Exchange API key for access token
curl -sS https://api.altdmp.io/v3/token/issue/ \
-H 'Content-Type: application/json' \
-d '{"api_key": "YOUR_API_KEY"}' \
| jq -r .access_token > /tmp/token.txt
# 2. List capital receivers
curl -sS "https://api.altdmp.io/v3/partners/capital-receivers/?search=Bunker&limit=20" \
-H "Authorization: Bearer $(cat /tmp/token.txt)" | jq .
Filter capital receivers (POST body)
curl -sS "https://api.altdmp.io/v3/partners/capital-receivers/?search=platform&ordering=-latest_valuation_usd&limit=100" \
-H "Authorization: Bearer $(cat /tmp/token.txt)" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"},
{"op": "gte", "field": "year_founded", "value": 2018},
{"op": "in", "field": "themes_keys", "value": ["themes_payments", "themes_climate_green_clean"]}
]
}
}' | jq .
Discover an investor and pull their portfolio
TOKEN=$(cat /tmp/token.txt)
# 1. Discover the investor — returns investor_type to determine which profile to call
INV=$(curl -sS "https://api.altdmp.io/v3/partners/investors/?investor_type=legal_entity&search=Temasek" \
-H "Authorization: Bearer $TOKEN" | jq -r '.results[0]')
UUID=$(echo "$INV" | jq -r '.uuid')
TYPE=$(echo "$INV" | jq -r '.investor_type')
# 2. Fetch the portfolio using the appropriate profile endpoint
# investor_type=legal_entity may be a capital allocator or capital receiver — try allocator first
if [ "$TYPE" = "capital_allocator" ]; then
URL="https://api.altdmp.io/v3/partners/capital-allocators/$UUID/investments/"
elif [ "$TYPE" = "fund" ]; then
URL="https://api.altdmp.io/v3/partners/funds/$UUID/investments/"
elif [ "$TYPE" = "person" ]; then
URL="https://api.altdmp.io/v3/partners/people/$UUID/investments/"
else
# For legal_entity, try capital-allocators first
URL="https://api.altdmp.io/v3/partners/capital-allocators/$UUID/investments/"
fi
curl -sS "$URL" -H "Authorization: Bearer $TOKEN" | jq .
Walk fund performance and AUM
FUND_UUID="your-fund-uuid-here"
curl -sS "https://api.altdmp.io/v3/partners/funds/$FUND_UUID/performance/?ordering=-date" \
-H "Authorization: Bearer $TOKEN" | jq .
curl -sS "https://api.altdmp.io/v3/partners/funds/$FUND_UUID/aum/?ordering=-date" \
-H "Authorization: Bearer $TOKEN" | jq .
Bootstrap reference data
# Cache enums and countries on app start
curl -sS "https://api.altdmp.io/v3/partners/reference-data/?type=enums,countries" \
-H "Authorization: Bearer $TOKEN" \
> reference_cache.json
# Use to populate filter dropdowns
jq '.enums.themes[] | "\(.key)\t\(.name)"' reference_cache.json
URL Cheat Sheet
| v2 call | v3 equivalent |
|---|---|
POST /api/v2/oauth/token | POST /v3/token/issue/ |
GET /api/v2/companies?query=X&countries=SGP | POST /v3/partners/capital-receivers/ with search=X and {"filters":{"all":[{"op":"eq","field":"headquarters_country_iso_alpha3","value":"SGP"}]}} |
GET /api/v2/companies/123 | GET /v3/partners/capital-receivers/{uuid}/ |
GET /api/v2/companies/201935876D/uen | GET /v3/partners/capital-receivers/?registration_number=201935876D |
GET /api/v2/companies/123/financials | GET /v3/partners/capital-receivers/{uuid}/ (funding block + financials[]) |
GET /api/v2/investors?query=X | GET /v3/partners/investors/?search=X |
GET /api/v2/investors/4 | GET /v3/partners/investors/ → find UUID → /capital-allocators/{uuid}/investments/ |
GET /api/v2/directors?query=X | GET /v3/partners/people/?role_type_key=person_association_director&search=X |
GET /api/v2/directors/4 | GET /v3/partners/people/{uuid}/ |
GET /api/v2/founders?query=X | GET /v3/partners/people/?role_type_key=person_association_founder&search=X |
GET /api/v2/founders/2 | GET /v3/partners/people/{uuid}/ |
GET /api/v2/auditors?query=X | GET /v3/partners/service-providers/?service_type=service_provider_type_audit&search=X |
GET /api/v2/auditors/2 | GET /v3/partners/service-providers/{uuid}/ |
GET /api/v2/capital-providers?category=fund-manager | GET /v3/partners/capital-allocators/ (no direct category filter) |
GET /api/v2/capital-providers/7034/ | GET /v3/partners/capital-allocators/{uuid}/ |
GET /api/v2/funds/?vintage_year_min=2020 | POST /v3/partners/funds/ with {"filters":{"all":[{"op":"gte","field":"vintage_year","value":2020}]}} |
GET /api/v2/funds/477 | GET /v3/partners/funds/{uuid}/ |
GET /api/v2/fund-performances/?fund_id=508 | GET /v3/partners/funds/{fund-uuid}/performance/ |
GET /api/v2/commitment-deals/?fund_id=764 | GET /v3/partners/funds/{fund-uuid}/commitments/ |
GET /api/v2/commitment-deals/?limited_partner_id=3521 | GET /v3/partners/capital-allocators/{allocator-uuid}/commitments/ |
GET /api/v2/people/?first_name=Arjun | GET /v3/partners/people/?search=Arjun |
Migration Checklist
- Update base URL from
https://api.alternatives.pe/api/v2/tohttps://api.altdmp.io/v3/partners/ - Replace
client_id/client_secretauth with the API-key flow onPOST /v3/token/issue/ - Confirm your subscription gives you access to the v3 endpoints you need (403 = contact support)
- Replace integer IDs with UUIDs in all API calls and persisted references
- Update pagination: parse
count,next,previous,resultsinstead of the v2data.data[]envelope - Convert
order_by/order_directionto singleorderingparameter (-prefix for descending) - Move advanced filters from query parameters to POST
filtersJSON bodies — afiltersquery parameter returns400 - Remove
sectorsusage and remap onto the v3 classification framework (themes,techs,business_models,industries,horizontals) - Update company lookups to
/capital-receivers/; look up by UEN via?registration_number= - Update capital-provider lookups to
/capital-allocators/; readprofile_typefrom the response - Replace auditor lookups with
/service-providers/?service_type=service_provider_type_audit - Consolidate director/founder calls to
/people/?role_type_key=person_association_director|founder - Move person
job_titlesreads to/people/{uuid}/roles/ - Handle the nested
legal_entityobject in profile responses - Update field names per the mapping tables (
first_name→given_name,last_name→family_name, etc.) - Update fund consumers: fetch performance via
/funds/{uuid}/performance/and AUM via/funds/{uuid}/aum/ - Migrate commitment-deal logic to the two nested commitments endpoints (per fund vs. per allocator)
- Adopt
/v3/partners/investors/and per-profile/investments/endpoints; expect investor records to split by allocation type - Integrate
GET /v3/partners/reference-data/to bootstrap filter dropdowns - Stop applying client-side FX — money fields are USD-normalized with
_usdsuffix - Smoke-test all endpoints in a non-prod environment before switching production traffic
Frequently Asked Questions
How long will v2 keep running?
v2 will be supported through a managed migration window communicated to each customer individually. Confirm your timeline with your customer support representative.
Do I need new credentials?
Yes. v3 issues API keys via PropelAuth, which are exchanged for short-lived bearer tokens via POST /v3/token/issue/. Request new credentials before starting your migration.
Will v3 expose everything v2 did?
Most v2 capability is preserved — either as a direct mapping or via a different shape. A small number of v2 fields are intentionally not surfaced (raw share-class IDs, news-sourced funding rounds, pre-money valuation). See the Coverage Gap Summary for the full list with workarounds.
What if my integration depends on a deprecated v2 field?
Email support@alternatives.pe with the specific field and use case. Many gaps have nearby v3 equivalents that can be adopted without losing functionality.
Filtering
Last updated: 19 August 2026
Every list endpoint in the Partner API accepts the same filter grammar: a filters object in a POST body, built from a fixed set of operators over a documented set of field names per endpoint. This page is the reference for that grammar — the operators, their exact matching behavior, the body shapes that are accepted, the supported filter fields for each endpoint, and the cases where a filter is accepted but not applied.
The endpoint pages repeat the fields most callers reach for first. This page is the authoritative list.
Where Filters Go
filters is a request-body parameter and is accepted only on POST. search, ordering, limit, and offset are query parameters and are accepted only on the query string. The two directions are not interchangeable, and swapping them never works:
| You send | Result |
|---|---|
filters in a POST body | Applied |
filters in ?filters=… | 400 Bad Request on both GET and POST |
?filters= with no value | Accepted — expresses no filter |
search / ordering / limit / offset in the body | Never takes effect. 400 Bad Request on most endpoints; discarded without an error on the rest — see Batch Endpoints |
search / ordering / limit / offset on the query string | Applied, alongside a POST filter body |
A POST request goes to the same path as the GET list — there is no /filter/ suffix:
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/?limit=50 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"},
{"op": "gte", "field": "latest_valuation_usd", "value": 50000000}
]
}
}'
resp = requests.post(
f"{BASE}/capital-receivers/",
headers=headers,
params={"limit": 50},
json={
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"},
{"op": "gte", "field": "latest_valuation_usd", "value": 50000000},
]
},
},
)
/v3/partners/investors/is the one endpoint that ignores a query-stringfiltersinstead of rejecting it, and it accepts a narrower filter grammar than the one on this page. See Investors → Advanced Filter (POST). Do not rely on the difference.
Filter Body Structure
filters must be a JSON object. A list or a scalar — {"filters": ["any"]} — returns 400 Bad Request. To ask for an unfiltered list, omit filters or send null or {}.
Two shapes are accepted at the root, and they can be combined in one body.
Logical form
The root holds all, any, or not, and each leaf condition names its own field:
{"filters": {"all": [{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"}]}}
all— AND. Takes an array.any— OR. Takes an array.not— NOT. Takes a single condition object, or an array, which is negated as a whole (the same as wrapping it inallfirst).
A leaf condition is {"op": …, "field": …, "value": …}. A bare leaf at the root is rejected — {"filters": {"op": "eq", "field": "…", "value": …}} returns 400 Bad Request, so wrap even a single condition in all.
Blocks nest to any depth. An entry inside all or any may itself be another all / any / not:
{
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"},
{"any": [
{"op": "gte", "field": "total_funding_usd", "value": 100000000},
{"op": "eq", "field": "is_raising_now", "value": true}
]},
{"not": {"op": "eq", "field": "trading_status_key", "value": "trading_status_ceased"}}
]
}
}
Field-keyed form
The root can instead key on the field name, with the condition as its value and no field inside it:
{"filters": {"year_founded": {"op": "gte", "value": 2015}}}
Multiple field keys at the root are ANDed together. Within one field key you may nest all / any / not and omit field from every leaf — the field name is taken from the key:
{
"filters": {
"domicile_country_iso_alpha3": {"op": "eq", "value": "SGP"},
"year_founded": {"all": [
{"op": "gte", "value": 2015},
{"op": "lte", "value": 2020}
]}
}
}
The field-keyed form does not work on the computed capital-receiver fields.
total_funding_usd,latest_valuation_usd,latest_operating_revenue_usd,operating_revenue_growth_yoy_pct,latest_investment_date,latest_investment_stage_name,latest_investment_stage_key, andcaptable_is_managedare backed by subqueries that are only attached when the endpoint sees the field inside afieldkey — which the field-keyed form does not produce.{"filters": {"latest_valuation_usd": {"op": "gte", "value": 50000000}}}returns400 Bad Requestnaming an internal column (filter_latest_valuation_usd). Use the logical form for these fields:{"filters": {"all": [{"op": "gte", "field": "latest_valuation_usd", "value": 50000000}]}}
financials_latest_financial_year_endhas the same restriction and more — see its caveat below. This is the reason to prefer the logical form generally: it is the only form every field supports.
Two shorthands are accepted in this form:
| Shorthand | Equivalent to |
|---|---|
{"themes_keys": ["themes_payments", "themes_climate_green_clean"]} | {"op": "in", "field": "themes_keys", "value": [...]} |
{"domicile_country_iso_alpha3": "SGP"} | {"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"} |
A field key may sit alongside a logical block at the root; the two are ANDed. The logical form is the better default for anything a machine generates — it is uniform, and every condition carries its own field name.
Rejected bodies
| Body | Result |
|---|---|
{"not": []}, {"not": {}}, {"not": {"all": []}} | 400 — a body asking to exclude rows must not return every row |
{"all": []}, {"any": []} | Accepted, permissive no-op — a caller who supplied no conditions |
{"all": ["oops"]} — a non-object where a condition was expected | 400 |
{"op": "range", "field": "…", "value": [1]} — range without exactly two values | 400 |
Malformed conditions return 400 in both root forms — {"all": ["oops"]} and {"name": {"all": ["oops"]}} behave the same way.
Operators
| Operator | Meaning | value shape | Case-sensitive |
|---|---|---|---|
eq | Equals | scalar | Yes |
ne | Does not equal | scalar | Yes |
in | Equals any of | array | Yes |
nin | Equals none of | array | Yes |
contains | Contains substring | string | No |
ncontains | Does not contain substring | string | No |
startswith | Starts with | string | No |
endswith | Ends with | string | No |
gt / gte | Greater than / or equal | number or date string | n/a |
lt / lte | Less than / or equal | number or date string | n/a |
range | Between two bounds, inclusive | array of exactly 2, low then high | n/a |
isnull | Value is null | true | n/a |
notnull | Value is not null | true | n/a |
An unrecognized operator is silently treated as
eq. It does not return400.{"op": "like", "field": "display_name", "value": "Acme"}returns200with the rows aneqwould have matched, so a typo inopreads as a working filter. Check operator spelling against the table above; do not rely on the API to reject one. (containsis the substring operator — there is nolike.)
Case sensitivity
The equality and set operators are case-sensitive. The substring operators are not. This catches people out, because the failure is an empty result set rather than an error:
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "sgp"}
That returns zero rows. "SGP" returns the Singapore-domiciled set.
| Case-sensitive | Case-insensitive |
|---|---|
eq, ne, in, nin | contains, ncontains, startswith, endswith |
Two things follow. For eq, ne, in, and nin, match the exact casing the API returns — take values from Reference Data or from a response body rather than typing them by hand. And prefer *_key fields over *_name fields for exact matching: keys are lowercase, underscore-delimited, and contractual, so there is no casing to get wrong. {"op": "eq", "field": "trading_status_key", "value": "trading_status_ceased"} is more robust than the same filter on trading_status_name.
This inconsistency is a known bug, not a design. A future release will make the equality and set operators case-insensitive too, matching the substring operators. A filter that already passes exact casing is unaffected by that change:
eqandinwould match the same rows, andneandninwould exclude the same rows. Getting the casing right today is therefore the safe move in both directions — whereas a filter that relies on a case mismatch to exclude something will start behaving differently.
range
value is an array of exactly two elements, low bound first, and both bounds are inclusive. Any other length returns 400 Bad Request.
{"op": "range", "field": "date_founded", "value": ["2015-01-01", "2020-12-31"]}
isnull and notnull
Pass true as the value. {"op": "isnull", "field": "latest_valuation_usd", "value": true} returns rows with no known valuation; notnull returns rows that have one.
The value is ignored. {"op": "isnull", "value": false} still means IS NULL — it does not invert to notnull. Use notnull for the other direction.
Dates
Date and date-time fields take ISO 8601 strings — "2020-01-01" for a date, "2026-08-19T00:00:00Z" for a timestamp — and work with eq, ne, gt, gte, lt, lte, and range.
Nulls and Filters
null means unknown. It is not zero and not false, and it never satisfies a comparison — so rows with a null in the filtered field are excluded from every gt / gte / lt / lte / range filter on that field, in both directions. Filtering {"op": "lt", "field": "total_funding_usd", "value": 1000000} does not return companies whose funding is unknown.
Use isnull when you want the unknowns, and any when you want both:
{"filters": {"any": [
{"op": "lt", "field": "total_funding_usd", "value": 1000000},
{"op": "isnull", "field": "total_funding_usd", "value": true}
]}}
Nullable booleans behave the same way. is_raising_now, is_open_to_co_investment, and the fund classification flags return null when nothing has been declared, which is distinct from false — an {"op": "eq", "value": false} filter returns only the explicit false rows. See Field Types and Nulls.
Keys and Display Names
Most taxonomy concepts are filterable two ways: a *_keys / *_key field taking the stable key, and a *_names / *_name field taking the display label. Filter on the key. Labels can be respelled without the underlying thing changing, which silently re-partitions anything matched on the display string.
{"op": "in", "field": "themes_keys", "value": ["themes_payments", "themes_climate_green_clean"]}
GET /partners/reference-data/?type=enums returns the valid keys for every such field. See Keys and Display Values for the full doctrine, including which fields are the key half of a pair with no _key suffix.
Deal filter fields are the exception — they match on display names only.
allocation_typetakes"Equity", not"equity", and there is noallocation_type_keyfilter field. See Capital Receiver Deal Filter Fields below.
Supported Filter Fields
The lists below are the supported filter field names for each endpoint — the contractual surface, and the only names covered by our compatibility guarantees. Build against these.
They are not an exhaustive account of what the filter parser will accept. A name that resolves to an internal database column or relation path is passed through to the query rather than rejected, so an unlisted name can appear to work; it can change or disappear in any release without notice. A name that resolves to nothing returns 400 Bad Request naming the internal columns it tried — that error text is diagnostic output, not a field list to build against.
Field names are per-endpoint. display_name is filterable on capital receivers, capital allocators, funds, and service providers, but the people endpoint has given_name and family_name instead.
Capital Receiver Filter Fields
POST /v3/partners/capital-receivers/
Identity and description — display_name, description, registration_number
Geography — domicile_country_name, domicile_country_iso_alpha3, headquarters_country_name, headquarters_country_iso_alpha3, headquarters_state_name, headquarters_city_name
Categorization — themes_names, themes_keys, horizontals_names, horizontals_keys, techs_names, techs_keys, business_models_names, business_models_keys, industries_codes
Status and attributes — trading_status_name, trading_status_key, is_female_founder, is_raising_now, captable_is_managed, year_founded, date_founded
Funding and financials — total_funding_usd, latest_valuation_usd, latest_investment_stage_name, latest_investment_stage_key, latest_investment_date, latest_operating_revenue_usd, operating_revenue_growth_yoy_pct, financials_latest_financial_year_end
ordering accepts display_name, year_founded, total_funding_usd, latest_valuation_usd, latest_operating_revenue_usd, operating_revenue_growth_yoy_pct, latest_investment_date, created_at, updated_at, last_updated_at.
The funding and financials fields are computed on demand — only when they appear in the filter body or in
ordering— so a plain list request pays nothing for them. Filter,ordering, and the responsefundingobject all use the same names. See Common Filter Fields for types and examples. All eight are restricted to the logical form; see the field-keyed form caveat.
financials_latest_financial_year_endis narrower than the rest, and it fails silently. It resolves through a separate lookup against a pre-computed view, which only recognizes a leaf carrying an explicitfieldkey, directly underall, with one ofeq,gt,gte,lt,lte. Everything else returns200with the condition dropped or misapplied:
Shape What happens {"all": [{"op": "gte", "field": "financials_latest_financial_year_end", "value": "2025-01-01"}]}Applied {"op": "range", …},ne,in,nin,isnull,notnullDropped — full unfiltered result set, 200{"financials_latest_financial_year_end": {"op": "gte", …}}(field-keyed)Dropped — full unfiltered result set, 200The leaf inside notInverted — returns exactly the rows you asked to exclude, 200The leaf inside anyANDed — narrower than the anyyou wroteUse only
eq/gt/gte/lt/lte, only directly underall, and never insidenotorany. For a two-sided window, passgteandlteas two conditions in the sameallrather thanrange.
Capital Allocator Filter Fields
POST /v3/partners/capital-allocators/
Identity and description — display_name, description
Geography — domicile_country_name, domicile_country_iso_alpha3, headquarters_country_name, headquarters_country_iso_alpha3
Allocator type — types_names, types_keys, preferred_allocation_type_name, preferred_allocation_type_key
Stated preferences — preferred_countries_names, preferred_countries_iso_alpha3, preferred_themes_names, preferred_themes_keys, preferred_horizontals_names, preferred_horizontals_keys, preferred_business_models_names, preferred_business_models_keys, preferred_techs_names, preferred_techs_keys, preferred_fund_types_names, preferred_fund_types_keys, preferred_allocation_subtypes_names, preferred_allocation_subtypes_keys, preferred_allocation_deal_types_names, preferred_allocation_deal_types_keys, preferred_industries_codes
Amounts — cheque_size_min, cheque_size_avg, cheque_size_max, dry_powder, median_valuation, current_allocation, target_allocation, stated_count_of_investments
Preference flags — is_open_to_first_time_fund, is_open_to_co_investment, has_preference_for_balanced_funds, has_preference_for_hybrid_funds, has_preference_for_special_situation_funds, has_preference_for_separate_account
ordering accepts display_name, cheque_size_min, cheque_size_avg, cheque_size_max, dry_powder, median_valuation, current_allocation, target_allocation, stated_count_of_investments, created_at, updated_at.
The
preferred_*fields are what an allocator states, not what it has done. To segment on actual behavior, compare againstactual_allocation_deal_typeson the response. Geography resolves through the allocator’s linked legal entity, so allocators backed by aPersonreturnnulland are excluded when a country filter is applied.
Fund Filter Fields
POST /v3/partners/funds/
Identity and description — display_name, description, fund_manager_name
Geography — domicile_country_name, domicile_country_iso_alpha3, headquarters_country_name, headquarters_country_iso_alpha3
Vehicle attributes — date_founded, vintage_year, status_name, status_key, structure, term_years
Stated preferences — preferred_countries_names, preferred_countries_iso_alpha3, preferred_themes_names, preferred_themes_keys, preferred_horizontals_names, preferred_horizontals_keys, preferred_business_models_names, preferred_business_models_keys, preferred_techs_names, preferred_techs_keys, preferred_allocation_types_names, preferred_allocation_types_keys, preferred_allocation_subtypes_names, preferred_allocation_subtypes_keys, preferred_allocation_deal_types_names, preferred_allocation_deal_types_keys, preferred_industries_codes
Classification flags — is_first_time_fund, is_raising_now, is_foia_reportable, is_captive_fund, is_single_deal_fund, is_continuation_fund, is_hybrid_fund, is_balanced_fund, is_special_situation_fund
Economics — management_fee_percentage, gp_commitment_percentage, hurdle_percentage, carry_percentage
ordering accepts display_name, vintage_year, term_years, created_at, updated_at.
Note
preferred_allocation_types_*here is plural, againstpreferred_allocation_type_*singular on capital allocators. The classification flags are nullable —nullmeans undeclared, notfalse.
Person Filter Fields
POST /v3/partners/people/ — given_name, family_name, location_country_name, location_country_iso_alpha3, date_of_birth
ordering accepts family_name, given_name, date_of_birth, created_at, updated_at.
Role and country filtering on people is done with query parameters, not filter-body fields.
role_type_key,role_type_name,domicile_country_iso_alpha3, andheadquarters_country_iso_alpha3go on the query string and combine with the body filters. Sending any of them insidefiltersreturns400 Bad Request. See People.
Person Role Filter Fields
POST /v3/partners/people/roles/ — person_uuid (required, see Batch Endpoints), role_type_key, role_type_name
Service Provider Filter Fields
POST /v3/partners/service-providers/ — display_name, description, legal_entity_uuid, service_type_key, service_type_name
This is the only list endpoint that exposes legal_entity_uuid as a filter field, which makes it the one place you can look a service provider up by the legal entity behind it.
Capital Receiver Deal Filter Fields
POST /v3/partners/capital-receivers/{uuid}/deals/
These fields apply on the per-company endpoint only. The batch POST /v3/partners/capital-receivers/deals/ accepts a filter body but applies nothing beyond its required capital_receiver_uuid IN filter — see Batch Endpoints.
Labels and classification — deal_label, self_declared_label, allocation_type, allocation_subtype, deal_transaction_type
Provenance — date, provenance, description, source
Amounts and shares — deal_size_usd, deal_transaction_size_usd, reported_deal_size_usd, post_money_valuation_usd, no_shares_issued, no_shares_bought, no_shares_sold
These match on display names, not keys — {"op": "eq", "field": "allocation_type", "value": "Equity"}. There is no allocation_type_key filter field; passing one returns 400 Bad Request. Because the values are display names, they are also case-sensitive under eq / ne / in / nin: "equity" returns zero deals.
transaction_label is accepted here and never applied — see Fields Accepted but Not Applied.
Batch Financials Filter Fields
POST /v3/partners/capital-receivers/financials/ — capital_receiver_uuid (required), financial_year_end, uuid
Fields Accepted but Not Applied
A small number of names are accepted by the filter parser and then not applied. The request succeeds with 200 OK and returns a result set wider than the filter implies — there is nothing in the response to indicate the condition was dropped. Do not use these:
| Endpoint | Field |
|---|---|
| Capital Receivers | funding_status |
| Capital Receivers | has_vc_transactions |
| People | nationality_name |
| People | nationality_iso_alpha3 |
| People | is_employee |
| People | associated_ca_types |
| Deals | transaction_label |
If your integration filters on one of these today, its results have never been restricted by that condition. Check the affected queries: the fix is either to drop the condition, or to reproduce it from a field that is applied.
transaction_labelon deals is the closest to a trap — filter deals withdeal_labelorself_declared_labelinstead.
We intend to make each of these return 400 Bad Request rather than pass silently. When that lands, a request using one of these names starts failing outright instead of succeeding with the wrong rows — so treat the list above as work to do now, not later.
These are the field names that never apply. Three other silent-drop cases are shape-dependent rather than name-dependent, and are covered where they arise: an unrecognized op, financials_latest_financial_year_end outside its supported shapes, and any condition beyond the required in on five of the batch endpoints.
Batch Endpoints
The batch endpoints take a required in filter on the parent UUID and return one flat, paginated result set across many parents, so you fetch a sub-resource for a page of entities in one request rather than one request per entity.
| Endpoint | Required in filter field | Additional conditions |
|---|---|---|
POST /capital-receivers/financials/ | capital_receiver_uuid | Applied — financial_year_end, uuid |
POST /people/roles/ | person_uuid | Applied — role_type_key, role_type_name |
POST /capital-receivers/deals/ | capital_receiver_uuid | Ignored |
POST /capital-receivers/news/ | capital_receiver_uuid | Ignored |
POST /capital-receivers/deal-share-types/ | capital_receiver_uuid | Ignored |
POST /capital-allocators/aum/ | capital_allocator_uuid | Ignored |
POST /funds/performance/ | fund_uuid | Ignored |
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/deals/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "capital_receiver_uuid", "value": [
"c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"fee788ac-cffe-46f0-9bb5-fedb62992bd8"
]}
]
}
}'
Rules, identical on every batch endpoint:
- The
infilter is required. Missing or empty returns400 Bad Request— these endpoints never return unscoped results. - The
inleaf must sit directly inside a root-levelall, exactly as shown above. The other body shapes this page documents are not recognized here:{"any": [...]}, a nested{"all": [{"all": [...]}]}, the field-keyed{"capital_receiver_uuid": {"op": "in", "value": [...]}}, and the list shorthand{"capital_receiver_uuid": [...]}each return400 Bad Requestsaying the IN filter is missing, even though the UUIDs are right there in the body. - Maximum 1,000 UUIDs per request. More returns
400, as does any value that is not a valid UUID. - Every returned row carries the parent UUID field, so you can join it back to the entity it belongs to.
- Pagination is by
limit/offseton the query string, as everywhere else. Alimitin the body never paginates anything, and on every batch endpoint exceptPOST /people/roles/it is discarded without a400— so a body-only pagination attempt returns the default page size with a200and no indication it was dropped.POST /capital-receivers/{uuid}/deals/behaves the same way. This is unrelated to the Applied / Ignored column above, which is only about extra filter conditions.
On the five endpoints marked “Ignored”, conditions beyond the required
infilter have no effect. The request returns200and the full row set for the UUIDs you passed. Nothing in the response marks the dropped condition, and an unsupported or misspelled field name does not error either — adding{"op": "eq", "field": "allocation_type", "value": "Equity"}to a batch deals request returns every deal for those companies, equity or not. Filter these results client-side, or call the per-entity endpoint where the fields are honored.
Errors
A rejected filter body returns 400 Bad Request with a message naming the problem — an unsupported ordering value, a range with the wrong number of bounds, a malformed condition, a field name that resolves to nothing, or a batch UUID list that is missing, oversized, or invalid.
Not everything wrong with a filter body is an error. These return 200 with results that do not match what you asked for, and nothing in the response says so:
| Cause | Effect |
|---|---|
Unrecognized op | Treated as eq |
| A field from Fields Accepted but Not Applied | Condition dropped |
financials_latest_financial_year_end outside its supported shapes | Condition dropped, or inverted under not |
Any condition beyond the required in on a batch endpoint marked “Ignored” | Condition dropped |
Wrong casing under eq / ne / in / nin | Zero rows, or — for ne / nin — nothing excluded |
Test a new filter against a small known result set before wiring it into a sync.
One case keys the message by the parameter at fault rather than using detail — filters passed on the query string. See 400 response bodies for the exact shapes.
Capital Receivers
Last updated: 25 August 2026
Capital receivers are companies and startups that have received investment. This is the most frequently accessed entity type in the Partner API.
Endpoints
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/capital-receivers/ | Subscription required |
POST | /v3/partners/capital-receivers/ | Subscription required |
GET | /v3/partners/capital-receivers/{uuid}/ | Subscription required |
GET | /v3/partners/capital-receivers/{uuid}/financials/ | Subscription required |
POST | /v3/partners/capital-receivers/financials/ | Subscription required |
GET | /v3/partners/capital-receivers/{uuid}/captable/ | Subscription required |
GET | /v3/partners/capital-receivers/{uuid}/investors/ | Subscription required |
GET | /v3/partners/capital-receivers/{uuid}/deals/ | Subscription required |
POST | /v3/partners/capital-receivers/{uuid}/deals/ | Subscription required |
POST | /v3/partners/capital-receivers/deals/ | Subscription required |
POST | /v3/partners/capital-receivers/deal-share-types/ | Subscription required |
GET | /v3/partners/capital-receivers/{uuid}/news/ | Subscription required |
POST | /v3/partners/capital-receivers/news/ | Subscription required |
List Capital Receivers
Returns a paginated list of capital receiver profiles.
curl "https://api.altdmp.io/v3/partners/capital-receivers/?search=shopback" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
resp = requests.get(f"{BASE}/capital-receivers/", params={"search": "shopback"}, headers=headers)
data = resp.json()
# data["results"] is the list, data["count"] is total matches
Example response (ShopBack):
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity": {
"uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"display_name": "Shopback",
"description": "ShopBack operates a consumer-facing cashback and rewards platform.",
"year_founded": 2014,
"date_founded": "2014-04-01",
"date_founded_precision": "month",
"is_female_founder": true,
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"headquarters": {
"country_name": "Singapore",
"country_iso_alpha3": "SGP",
"state_name": null,
"city_name": "Singapore"
},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{
"reg_number": "201411189G",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
],
"website_url": "https://www.shopback.sg"
},
"captable_source": {"type": "managed"},
"description": "ShopBack operates a consumer-facing cashback and rewards platform.",
"themes": [
{"key": "themes_payments", "name": "Payments"},
{"key": "themes_business_applications_saas", "name": "Business Applications / SaaS"}
],
"horizontals": [{"key": "horizontals_marketplaces", "name": "Marketplaces"}],
"techs": [{"key": "techs_fintech", "name": "FinTech"}],
"business_models": [{"key": "business_models_b2c", "name": "B2C (Business-to-Consumer)"}],
"industries": [{"code": "0602", "description": "Retail Trade (Except Vehicles)"}],
"is_raising_now": false,
"last_updated_at": "2025-10-16T07:33:30Z",
"funding": {
"latest_investment_date": "2022-12-13",
"latest_investment_stage_name": "Series F",
"latest_investment_stage_key": "series_f",
"latest_valuation_usd": 925652927.23,
"latest_valuation_date": "2022-12-13"
},
"latest_financials": {
"financial_year_end": "2025-03-31",
"operating_revenue_usd": 96318754.34,
"earnings_before_tax_usd": -12045980.11,
"liabilities_usd": 184220310.00,
"operating_revenue_growth_yoy_pct": -2.40,
"is_audited": true,
"is_consolidated": false,
"is_restated": false,
"audit_opinion": {"key": "audit_opinion_unqualified", "name": "Unqualified Opinion"}
}
}
]
}
Identity fields live on
legal_entity, not on the profile.display_name,year_founded,date_founded,date_founded_precision,domicile_country,headquarters,trading_status, andregistration_numbersare all nested underlegal_entity— the capital receiver profile itself carries onlyuuid,description, the classification arrays,captable_source,is_raising_now,last_updated_at,funding, andlatest_financials. See Data Model.
fundingandlatest_financialsarenullwhen the company has no deals or no filed financials respectively.
List Query Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Matches company name, alternate names, and registration number |
registration_number | string | Filter by company registration number |
ordering | string | Field to sort by. Prefix with - for descending (e.g. -last_updated_at) |
limit | integer | Results per page (default: 20) |
offset | integer | Pagination offset |
total_funding_min | number | Minimum total equity raised (USD) |
total_funding_max | number | Maximum total equity raised (USD) |
is_raising_nowis a filter field on the advancedPOSTfilter, not aGETquery parameter.
Advanced Filter (POST)
Use POST with a JSON body for complex filters — range queries, multi-value matches, and boolean logic. The body accepts only the filters object; pass search, ordering, limit, and offset as query parameters. filters cannot go the other way — a value in ?filters= returns 400 Bad Request on both GET and POST.
Filter grammar, operators, and the supported filter field list are on the Filtering page. In short:
filtersmust be an object whose top level isall(AND),any(OR), ornot(NOT) — wrap even a single condition inall. Blocks nest to any depth.eq,ne,in, andninare case-sensitive; the substring operators are not. Use theall/any/notform rather than the field-keyed shorthand: the computed funding and financials fields below are only honored in that form.
# Singapore companies at Series B or later
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"},
{"op": "in", "field": "latest_investment_stage_name",
"value": ["Series B", "Series C", "Series D", "Series E", "Series F"]}
]
}
}'
resp = requests.post(
f"{BASE}/capital-receivers/",
headers=headers,
json={
"filters": {
"all": [
{"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"},
{"op": "in", "field": "latest_investment_stage_name",
"value": ["Series B", "Series C", "Series D", "Series E", "Series F"]},
]
},
},
params={"limit": 20, "offset": 0},
)
Common Filter Fields
| Field | Type | Example |
|---|---|---|
headquarters_country_iso_alpha3 | string | "SGP" |
domicile_country_iso_alpha3 | string | "SGP" |
latest_investment_stage_name | string | "Series A" |
latest_investment_stage_key | string | "series_a" |
latest_investment_date | date string | "2022-12-13" |
latest_valuation_usd | number | 50000000 |
latest_operating_revenue_usd | number | 10000000 |
operating_revenue_growth_yoy_pct | number | 15.0 |
total_funding_usd | number | 5000000 |
financials_latest_financial_year_end | date string | "2023-01-01" |
captable_is_managed | boolean | true |
is_female_founder | boolean | true |
is_raising_now | boolean | false |
year_founded | integer | 2018 |
date_founded | date string | "2014-04-01" |
date_foundedfilters on the full founding date and supportsgte,lte,range, andeq. The response also exposesdate_founded_precision("year","month", or"day") so you can tell how exact adate_foundedvalue is.year_founded(year only) is retained for backward compatibility; sorting with?ordering=year_foundedis unchanged, though it now orders by the full founding date.
financials_latest_financial_year_end,latest_investment_stage_name,latest_investment_stage_key,latest_investment_date,latest_operating_revenue_usd,operating_revenue_growth_yoy_pct,latest_valuation_usd, andtotal_funding_usdare computed on demand — only when they appear in the filter body or inordering— so a plain list request pays nothing for them.
latest_investment_dateis the date of a company’s most recent active deal. Sort by it (?ordering=-latest_investment_date) or filter by it (e.g.{"op": "gte", "field": "latest_investment_date", "value": "2026-01-01"}) to pull only recently-funded companies — the v3 equivalent of the v2date_of_last_roundsort. Companies with no deals sort last in both directions.
These field names match the response
fundingobject, so you read, filter, and sort by the same key (e.g.?ordering=-total_funding_usd).
captable_is_managed:truereturns companies with a managed cap table (full transaction-level data available via/captable/and/investors/);falsereturns snapshot-only companies.null(no filter) includes both. Companies with no cap table at all are excluded from botheq:trueandeq:falsequeries.
Filter Examples
# Companies that filed financials for FY2023 or later
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filters": {"all": [{"op": "gte", "field": "financials_latest_financial_year_end", "value": "2023-01-01"}]}}'
# Companies with a managed cap table (full transaction-level data available)
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filters": {"all": [{"op": "eq", "field": "captable_is_managed", "value": true}]}}'
# Companies with a snapshot cap table only
curl -X POST https://api.altdmp.io/v3/partners/capital-receivers/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filters": {"all": [{"op": "eq", "field": "captable_is_managed", "value": false}]}}'
# Companies that filed financials for FY2023 or later
resp = requests.post(
f"{BASE}/capital-receivers/",
headers=headers,
json={"filters": {"all": [{"op": "gte", "field": "financials_latest_financial_year_end", "value": "2023-01-01"}]}},
)
# Companies with a managed cap table
resp = requests.post(
f"{BASE}/capital-receivers/",
headers=headers,
json={"filters": {"all": [{"op": "eq", "field": "captable_is_managed", "value": True}]}},
)
Get Capital Receiver Detail
Returns the full profile for a single capital receiver, including additional fields not present in the list response.
curl "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/" \
-H "Authorization: Bearer YOUR_TOKEN"
uuid = "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67"
detail = requests.get(f"{BASE}/capital-receivers/{uuid}/", headers=headers).json()
The detail response returns every field from the list response except latest_financials, with these differences: legal_entity is the fuller variant (adding alternate_names, website_url, email, phone, founders, directors, auditors), funding is extended with the full equity/debt breakdown, and seven additional top-level fields are present.
{
"uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity": {
"uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"display_name": "Shopback",
"description": "ShopBack operates a consumer-facing cashback and rewards platform.",
"year_founded": 2014,
"date_founded": "2014-04-01",
"date_founded_precision": "month",
"is_female_founder": true,
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"headquarters": {
"country_name": "Singapore",
"country_iso_alpha3": "SGP",
"state_name": null,
"city_name": "Singapore"
},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{
"reg_number": "201411189G",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
],
"alternate_names": [
{"name": "Shopback Pte. Ltd.", "type": "Legal Name", "type_key": "alt_name_legal_name"}
],
"website_url": "https://www.shopback.sg",
"email": null,
"phone": null,
"founders": [
{"uuid": "f2eac778-a47b-497e-a4c6-ddd71335a404", "name": "Shanru Lai"},
{"uuid": "9c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f", "name": "Henry Chan"}
],
"directors": [
{"uuid": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "name": "Willson Cuaca"}
],
"auditors": [
{"uuid": "ad9be164-4e19-4822-987e-54efe73d8974", "name": "Ernst & Young LLP"}
]
},
"captable_source": {"type": "managed"},
"description": "ShopBack operates a consumer-facing cashback and rewards platform.",
"themes": [{"key": "themes_payments", "name": "Payments"}],
"horizontals": [{"key": "horizontals_marketplaces", "name": "Marketplaces"}],
"techs": [{"key": "techs_fintech", "name": "FinTech"}],
"business_models": [{"key": "business_models_b2c", "name": "B2C (Business-to-Consumer)"}],
"industries": [{"code": "0602", "description": "Retail Trade (Except Vehicles)"}],
"is_raising_now": false,
"last_updated_at": "2025-10-16T07:33:30Z",
"funding": {
"latest_investment_date": "2022-12-13",
"latest_investment_stage_name": "Series F",
"latest_investment_stage_key": "series_f",
"latest_valuation_usd": 925652927.23,
"latest_valuation_date": "2022-12-13",
"reported_and_filed_equity_usd": 203586016.85,
"filed_equity_usd": 203586016.85,
"reported_equity_usd": null,
"reported_and_filed_debt_usd": null,
"filed_debt_usd": null,
"reported_debt_usd": null,
"total_funding_usd": 203586016.85,
"latest_investment_amount": 50000000.00
},
"financials": [
{
"financial_year_end": "2025-03-31",
"operating_revenue_usd": 96318754.34,
"earnings_before_tax_usd": -12045980.11,
"liabilities_usd": 184220310.00,
"operating_revenue_growth_yoy_pct": -2.40,
"is_audited": true,
"is_consolidated": false,
"is_restated": false,
"audit_opinion": {"key": "audit_opinion_unqualified", "name": "Unqualified Opinion"}
}
],
"financial_statements_audited": [
{
"year": 2024,
"date_of_file": "2025-06-30",
"url": "https://assets.alternatives.pe/assets/file-attachments/996955694181.pdf?Expires=...&Signature=...&Key-Pair-Id=..."
}
],
"financial_statements_extracted": [
{
"year": 2024,
"date_of_file": null,
"url": "https://assets.alternatives.pe/assets/file-attachments/08b6d224b06e.pdf?Expires=...&Signature=...&Key-Pair-Id=..."
}
],
"funding_status": "VC-Funded",
"has_vc_transactions": true,
"has_pe_transactions": false,
"has_ma_transactions": false,
"has_debt_transactions": false,
"has_liquidity_events": false,
"has_distressed_transactions": false,
"has_partial_exits": true
}
The detail-only fields
| Field | Type | Description |
|---|---|---|
financials | array | Condensed financial history, newest financial year end first. Nine fields per row — not the same shape as the /financials/ endpoint, which returns the full statement. Use /financials/ when you need the complete breakdown. |
financial_statements_audited | array | Audited financial-statement documents: year, date_of_file, and a signed, expiring url — see the note below. |
financial_statements_extracted | array | Machine-extracted statement documents, same shape as above. |
funding_status | string | One of "Public Listed", "PE-Funded", "VC-Funded", "Other Unlisted", "Unfunded startup", or "n/a". |
has_vc_transactions / has_pe_transactions / has_ma_transactions / has_debt_transactions / has_liquidity_events / has_distressed_transactions / has_partial_exits | boolean, nullable | Whether the company has any deal of that kind on record. |
The
urlvalues are signed and expire one hour after the response. Every request mints a fresh signature, and theExpiresparameter in the URL carries the exact deadline as a Unix timestamp — read it rather than hard-coding a lifetime, in case the window changes. Three consequences:
- Download promptly; don’t store the URL. A URL persisted anywhere — a database, a queue, a cached response — is dead within the hour. Re-request the detail endpoint to mint a new one.
- An expired link is not a JSON error. The asset host returns
403 Forbiddenwith an XML body (<Error><Code>AccessDenied</Code></Error>), not the JSON error shape the rest of the API uses. Handle it separately from an API error response.- Treat a live URL as a credential. The signature alone authorizes the download — no
Authorizationheader is involved — so anyone holding the link can fetch the document until it expires.
The funding object
Monetary amounts are returned as numbers to two decimal places, or null. Equity and debt are each broken down into filed, reported, and their combined reported-and-filed total:
| Field | Description |
|---|---|
filed_equity_usd | Equity from official filings (or, for some domiciles, paid-up capital) |
reported_equity_usd | Equity from reported (e.g. announced) rounds not yet reflected in filings |
reported_and_filed_equity_usd | filed_equity_usd + reported_equity_usd |
filed_debt_usd / reported_debt_usd / reported_and_filed_debt_usd | The equivalent breakdown for debt |
total_funding_usd | reported_and_filed_equity_usd + reported_and_filed_debt_usd |
latest_valuation_usd / latest_valuation_date | Most recent known valuation and its date |
latest_investment_amount / latest_investment_date / latest_investment_stage_name / latest_investment_stage_key | Most recent funding round summary |
nullfunding amounts. A funding amount isnullwhen it is unknown or known to net to zero — these fields never return0.00. As a result, companies whose funding rolls up to zero sort to the end of funding-based orderings in both directions, and are excluded from numeric range filters (gte/lte, and thetotal_funding_min/total_funding_maxfilters), since anullvalue never satisfies a numeric comparison.
Public-listed companies. Companies classified as public no longer return funding or valuation — every amount in the
fundingobject (andlatest_valuation_usd) isnull, since a public company has a market capitalization rather than private funding.funding_statusis still populated (e.g."Public Listed").
What counts toward totals. Funding totals count all primary funding across a company’s deals, regardless of deal subtype or type. Secondary transactions are never included.
Cap Table
Returns the current shareholding structure. The shape of the response depends on captable_source.type — always check this field before interpreting results.
curl "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/captable/" \
-H "Authorization: Bearer YOUR_TOKEN"
captable = requests.get(f"{BASE}/capital-receivers/{uuid}/captable/", headers=headers).json()
source_type = captable["captable_source"]["type"] # "managed" or "snapshot"
Managed Cap Table Response
When captable_source.type is "managed", the cap table is computed from transaction records. Investment amounts and ownership-hierarchy rollups are available.
Every share metric comes in two variants: _absolute is the holding recorded against the shareholder itself, and _aggregate rolls in the holdings of its child_entities (SPVs and other entities it controls). For a shareholder with no children the two are identical.
{
"count": 4,
"next": null,
"previous": null,
"results": [
{
"shareholder": {
"uuid": "37c44afc-e55e-420c-bb2a-f9225a0d1c8e",
"name": "East Ventures Fund 2",
"type_key": "capital_allocator",
"type": "CapitalAllocatorProfile",
"allocation_type": "Equity"
},
"shares_issued_absolute": 1500000,
"shares_issued_aggregate": 1500000,
"shares_bought_secondary_absolute": 0,
"shares_bought_secondary_aggregate": 0,
"shares_sold_absolute": 250000,
"shares_sold_aggregate": 250000,
"total_invested_usd_absolute": 7500000.0,
"total_invested_usd_aggregate": 7500000.0,
"is_held_in_treasury": false,
"shares_currently_held_absolute": 1250000,
"shares_currently_held_aggregate": 1250000,
"percentage_held_absolute": 4.80,
"percentage_held_aggregate": 4.80,
"holding_value_usd": 50000000.00,
"child_entities_count": 0,
"child_entities": []
}
],
"captable_source": {"type": "managed"},
"as_of_date": "2026-08-07",
"aggregations": {
"shares_issued_aggregate": 26000000,
"shares_bought_secondary_aggregate": 0,
"shares_sold_aggregate": 250000,
"total_invested_usd_aggregate": 203586016.85,
"shares_currently_held_aggregate": 26000000,
"percentage_held_aggregate": 100.00,
"holding_value_usd": 925652927.23
}
}
| Field | Type | Notes |
|---|---|---|
shareholder | object | uuid, name, type_key, and type. Join on type_key — one of capital_allocator, capital_receiver, fund, legal_entity, person, shareholder_group, or other — and use type for display only. See Buyer and Seller Objects for how to route uuid by type_key. allocation_type is added when the shareholder is a capital allocator that has declared a preferred allocation type. Two special rows represent a group rather than a named shareholder, and both carry a null uuid: ESOP ({"uuid": null, "name": "ESOP", "type_key": null, "type": null}) and pooled minorities ({"uuid": null, "name": "Other Shareholders", "type_key": "other", "type": "Other"}). |
shares_issued_* / shares_bought_secondary_* / shares_sold_* / shares_currently_held_* | integer | Share counts. |
total_invested_usd_* | number, nullable | Cash invested in USD. |
percentage_held_* / holding_value_usd | number, nullable | percentage_held_* is a percentage — 18.50 means 18.5% of the company. |
is_held_in_treasury | boolean | Shares held in treasury by the company itself. |
child_entities_count / child_entities | integer / array | Controlled entities whose holdings roll into the _aggregate figures. Each entry has the same shape as a top-level row, so the structure nests. |
Snapshot Cap Table Response
When captable_source.type is "snapshot", data is sourced from a periodic shareholder register. Investment-amount data is not available.
{
"count": 12,
"next": null,
"previous": null,
"results": [
{
"shareholder": {"uuid": "...", "name": "Temasek Holdings", "type_key": "legal_entity", "type": "LegalEntity"},
"number_of_shares": 5000000,
"percentage_held": 35.00000,
"is_former_shareholder": false,
"start_date": "2021-03-15",
"end_date": null
}
],
"captable_source": {"type": "snapshot"},
"as_of_date": "2024-12-31",
"aggregations": null
}
shareholder.type_key here is one of person, legal_entity, shareholder_group, or alt — the last for a register entry recorded only as a name, in which case shareholder.uuid is null. Join on type_key, not on type. aggregations is always null for snapshot cap tables.
percentage_held is a number and a percentage — 35.00000 means 35% of the company. It was a quoted string until 2026-08-14. Note that it carries five decimal places here, where the managed cap table’s percentage_held_absolute / _aggregate carry two.
When the company has no cap table at all — no transactions and no snapshot on file — the response drops the pagination keys entirely and returns just
{"captable_source": {...}, "as_of_date": null, "results": [], "aggregations": null}. Readresultsrather than assumingcountis present.
/investors/returnsHTTP 400for snapshot companies — use/captable/instead.
Investors
Returns investor-centric aggregates for companies with a managed cap table. Each row represents one investor’s aggregate position.
curl "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/investors/" \
-H "Authorization: Bearer YOUR_TOKEN"
investors = requests.get(f"{BASE}/capital-receivers/{uuid}/investors/", headers=headers).json()
Example response (ShopBack):
{
"count": 24,
"next": null,
"previous": null,
"results": [
{
"uuid": "37c44afc-e55e-420c-bb2a-f9225a0d1c8e",
"name": "East Ventures Fund 2",
"investor_type": "fund",
"registration_numbers": [
{
"reg_number": "201411189G",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
],
"first_investment_date": "2019-04-30",
"latest_investment_date": "2022-03-01",
"shares_currently_held": 1250000.0,
"current_share_holding_percentage": 4.8,
"total_shares_allocated": 1500000.0,
"total_secondary_shares": 0.0,
"total_shares_sold": 250000.0,
"amount_invested_usd": 7500000.0,
"investment_by_stage_amount_usd": {
"pre_seed": 0.0,
"seed": 0.0,
"series_a": 7500000.0,
"series_b": 0.0,
"series_c_and_beyond": 0.0,
"other": 0.0
}
}
]
}
| Field | Type | Notes |
|---|---|---|
uuid / name / investor_type | string | The investor. investor_type is a key, not a label — one of capital_allocator, fund, capital_receiver, legal_entity, person, shareholder_group, or service_provider — and uuid is the ID to use with that key’s detail endpoint. |
registration_numbers | array | Present for entity-backed investors: reg_number, authority_type, authority_name. |
registration_number | string, nullable | Present instead of registration_numbers for person investors — a single identifier rather than a list. |
shares_* / current_share_holding_percentage / amount_invested_usd | number, nullable | current_share_holding_percentage is a percentage — 12.5 means 12.5%. |
investment_by_stage_amount_usd | object | Always the same six buckets: pre_seed, seed, series_a, series_b, series_c_and_beyond, other. Buckets with no investment return 0.0 rather than being omitted. |
An investor row carries either
registration_numbers(a list, for legal entities, capital allocators, and funds) orregistration_number(a single string, for people) — never both. Check for whichever key is present rather than assuming one.
Deals
Returns funding rounds and individual transactions for a capital receiver. ShopBack, for example, has 25 recorded deals.
curl "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/deals/" \
-H "Authorization: Bearer YOUR_TOKEN"
deals = requests.get(f"{BASE}/capital-receivers/{uuid}/deals/", headers=headers).json()
Example response (ShopBack Series F):
{
"count": 25,
"next": "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/deals/?limit=20&offset=20",
"previous": null,
"results": [
{
"uuid": "3869e63e-9b89-4986-9937-b7b21d2a2234",
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"date": "2022-12-13",
"investment_quarter": "Q4 2022",
"first_investment_date": "2022-07-20",
"last_investment_date": "2023-05-08",
"self_declared_label": "Series F",
"allocation_deal_type_name": "Series F",
"allocation_deal_type_key": "series_f",
"allocation_type_key": "equity",
"allocation_type_name": "Equity",
"allocation_subtype_key": "venture_capital",
"allocation_subtype_name": "Venture Capital (VC)",
"share_class": "Ordinary, Series F Preferred",
"no_shares_issued": 23023201,
"deal_size_usd": null,
"reported_deal_size_usd": null,
"post_money_valuation_usd": 925652927.23,
"price_per_share_usd": 40.0,
"description": "ShopBack, Southeast Asia's leading cashback and rewards platform, has closed an $80M Series F round...",
"headline": "ShopBack Secures $80M in Series F Funding Round",
"count_of_transactions": 14,
"transactions": [
{
"uuid": "05eaa0d4-a73f-48f7-ad5b-04f0daf918d3",
"date": "2022-12-13",
"nature_of_transaction": "Primary",
"transaction_type": "Series F",
"allocation_type_key": "equity",
"allocation_type_name": "Equity",
"allocation_subtype_key": "venture_capital",
"allocation_subtype_name": "Venture Capital (VC)",
"share_class": "Series F Preferred",
"number_of_shares": 2000000,
"transaction_size_usd": 80000000.0,
"price_per_share_usd": 40.0000,
"buyer": {
"uuid": "9f8e7d6c-5b4a-3928-1706-f5e4d3c2b1a0",
"name": "GIC Private Limited",
"type_key": "legal_entity",
"type": "LegalEntity",
"registration_numbers": [
{
"reg_number": "198100869P",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
]
},
"seller": {
"uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"name": "Shopback",
"type_key": "capital_receiver",
"type": "CapitalReceiverProfile",
"registration_numbers": [
{
"reg_number": "201411189G",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
]
}
}
]
}
]
}
Deal Fields
| Field | Type | Description |
|---|---|---|
uuid | string | The deal’s own UUID — stable across requests, so use it to deduplicate or to key deals in your own store. |
capital_receiver_uuid | string, nullable | The company the deal belongs to. Present on the per-company endpoint too, not only the batch endpoint. |
date | date string | Deal date. |
investment_quarter | string, nullable | Calendar quarter of date, e.g. "Q4 2022". |
first_investment_date / last_investment_date | date string, nullable | First and last transaction dates within the round; both fall back to date when the round has a single dated event. |
self_declared_label | string, nullable | The round name as the company describes it. Can differ from allocation_deal_type_name. |
allocation_deal_type_name / allocation_deal_type_key | string, nullable | Normalized round stage, e.g. "Series F" / "series_f". |
allocation_type_name / allocation_type_key | string, nullable | Asset class, e.g. "Equity" / "equity". |
allocation_subtype_name / allocation_subtype_key | string, nullable | Sub-classification, e.g. "Venture Capital (VC)" / "venture_capital". |
share_class | string, nullable | All distinct share classes across the round’s transactions, comma-separated and alphabetically sorted. A round issuing two classes returns "Ordinary, Series F Preferred". For a per-transaction class read transactions[].share_class. |
no_shares_issued | integer, nullable | Shares issued by the round. |
deal_size_usd | number, nullable | Round size in USD when the deal’s provenance is not Reported (i.e. it is filed or otherwise sourced). |
reported_deal_size_usd | number, nullable | Round size in USD when the deal’s provenance is Reported. At most one of these two is ever populated — the other is null. Both are null when no amount is known. Sum the pair, don’t pick one, if you want total round size across a mixed result set. |
post_money_valuation_usd | number, nullable | Post-money valuation in USD. |
price_per_share_usd | number, nullable | Highest per-share price across the round’s transactions, falling back to the deal-level price when no transaction records one. |
description | string, nullable | Body of the linked news article, falling back to the deal’s public notes. |
headline | string, nullable | Headline of the linked news article, falling back to the deal’s public notes. |
count_of_transactions | integer | Number of transactions in transactions. |
transactions | array | Individual buy/sell events making up the round. |
Transaction Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Transaction UUID. |
date | date string | Transaction date — can differ from the deal’s date. |
nature_of_transaction | string, nullable | e.g. "Primary", "Secondary". |
transaction_type | string, nullable | Transaction-level stage label, e.g. "Series F". |
allocation_type_key / allocation_type_name / allocation_subtype_key / allocation_subtype_name | string, nullable | Transaction-level classification, which can differ from the deal-level values. |
share_class | string, nullable | The single share class for this transaction. |
number_of_shares | integer | Shares transacted. |
transaction_size_usd | number, nullable | Cash plus non-cash consideration in USD. null when it nets to zero. |
price_per_share_usd | number, nullable | Price per share, rounded to four decimal places — e.g. 40.0000. The deal-level price_per_share_usd is the same figure carried at full stored precision, so the two can print with a different number of trailing digits. |
buyer / seller | object, nullable | The counterparties. null when the side is not recorded. |
Buyer and Seller Objects
| Field | Type | Description |
|---|---|---|
uuid | string, nullable | Identifier of the counterparty, in whichever namespace type_key names. |
name | string, nullable | Display name. |
type_key | string, nullable | What kind of thing uuid is — join on this. One of capital_allocator, capital_receiver, fund, legal_entity, person, or shareholder_group. |
type | string, nullable | Human-readable label for the same thing. Presentation only — do not join on it. |
registration_numbers | array | Present for entity counterparties: a list of {reg_number, authority_type, authority_name}. |
registration_number | string, nullable | Present instead for person counterparties — a single string. |
allocation_type | string | Added when the counterparty is a capital allocator that has declared a preferred allocation type, e.g. "Equity". |
uuid is not always a legal-entity ID. It points at the most specific record the counterparty has, and type_key tells you which. A firm that has a capital allocator profile returns that profile’s uuid with type_key: "capital_allocator"; the same firm without one returns its legal-entity uuid with type_key: "legal_entity". Joining buyer.uuid against a single namespace without branching on type_key will silently drop rows.
Route by type_key:
type_key | Use uuid with |
|---|---|
capital_allocator | /capital-allocators/{uuid}/ |
capital_receiver | /capital-receivers/{uuid}/ — for a seller on a primary round this matches the deal’s own capital_receiver_uuid |
fund | /funds/{uuid}/ |
person | /people/{uuid}/ |
legal_entity | No detail endpoint. Use it as a correlation key to group rows for the same registered company |
shareholder_group | No detail endpoint. name and uuid are all that is exposed |
Read
type_key, nottype.typecurrently shows values like"CapitalReceiverProfile", but a future release changes what it presents — see Keys and Display Values.
Every amount on a deal row is a JSON number. Deal-level
deal_size_usd,reported_deal_size_usd,post_money_valuation_usd,price_per_share_usd, and bothtransactions[]amounts.transactions[].price_per_share_usdwas a quoted string until 2026-08-14 and is no longer.
Filter Deals via POST
Use POST with a JSON body to filter deals by type, date, or other attributes. Supports the same operators and logical combinators (all, any, not) as the main list filter, with the same requirement that filters starts with one of them.
Deal Filter Fields
Deal filter fields match on display names, not keys — allocation_type takes "Equity", not "equity". There is no allocation_type_key filter field; passing one returns 400 Bad Request listing the valid fields.
| Field | Type | Example |
|---|---|---|
date | date string | "2020-01-01" |
deal_label | string | "Series A" |
self_declared_label | string | "Series A" |
allocation_type | string | "Equity" |
allocation_subtype | string | "Venture Capital (VC)" |
deal_transaction_type | string | "Seed", "Series A" |
deal_size_usd | number | 5000000 |
post_money_valuation_usd | number | 50000000 |
no_shares_issued | integer | 1000000 |
no_shares_bought | integer | 500000 |
no_shares_sold | integer | 100000 |
# Only equity rounds after 2020
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/deals/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "allocation_type", "value": "Equity"},
{"op": "gte", "field": "date", "value": "2020-01-01"}
]
}
}'
Batch Deals via POST
Use POST /v3/partners/capital-receivers/deals/ (note: no {uuid} in the path) to pull deals for many companies in one paginated request instead of calling the per-company .../{uuid}/deals/ endpoint once per company. The body must contain a non-empty capital_receiver_uuid in filter; up to 1,000 UUIDs are accepted per request. Each returned deal row carries a capital_receiver_uuid field so you can join it back to the company it belongs to.
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/deals/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "capital_receiver_uuid", "value": [
"c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"fee788ac-cffe-46f0-9bb5-fedb62992bd8"
]}
]
}
}'
Deal rows use exactly the same shape as the per-company deals endpoint — including capital_receiver_uuid, which is present on both — so you can point the same parsing code at either.
- A missing or empty
capital_receiver_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
Batch Deal Share Types via POST
Use POST /v3/partners/capital-receivers/deal-share-types/ to pull distinct deal-share-type rows for many companies in one paginated request. It returns a flat, deduplicated row for each unique (capital_receiver_uuid, deal_uuid, share_class, transaction_type) combination — a lightweight alternative to fetching full deals per company when you only need the share classes and transaction types issued. The body must contain a non-empty capital_receiver_uuid in filter; up to 1,000 UUIDs are accepted per request.
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/deal-share-types/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "capital_receiver_uuid", "value": [
"c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"fee788ac-cffe-46f0-9bb5-fedb62992bd8"
]}
]
}
}'
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"deal_uuid": "9b1f2c3d-4e5a-6b7c-8d9e-0f1a2b3c4d5e",
"deal_type_name": "Secondary Transaction",
"deal_type_key": "other_equity_secondary_transaction",
"share_class": "Ordinary",
"transaction_type": "Secondary Transaction"
}
]
}
Every field except capital_receiver_uuid is nullable. deal_type_name / deal_type_key are the deal’s normalized stage (the same values as allocation_deal_type_name / allocation_deal_type_key on a full deal row), and transaction_type is the transaction’s type display name — not a key, and not "primary" / "secondary".
- A missing or empty
capital_receiver_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
Financials
Returns historical financial records ordered by most recent financial year end first. Each row includes year-over-year growth annotations for revenue, expenses, earnings, and liabilities. Each monetary metric is available in both its original reporting currency (bare field, e.g. operating_revenue) and USD-normalized (_usd suffix, e.g. operating_revenue_usd); reporting_currency identifies the source currency. In v2, revenue, EBIT, and valuation values were imported as USD — v3 preserves those same values in the _usd fields while also exposing the original reporting-currency figure.
Growth-% values are capped at ±1000%. Every year-over-year growth field (the
annual_*_yoy_growth_pctfields here, andoperating_revenue_growth_yoy_pcton the list endpoint) returnsnullwhen the computed change exceeds +1000% or falls below −1000%. Values at exactly ±1000% are retained. This suppresses meaningless swings off a near-zero base. Anulltherefore means the value is missing, has a zero denominator, or is out of bounds — and out-of-bound rows are excluded from numeric range filters and sort to the end oforderingon these fields, sincenullnever satisfies a numeric comparison.
curl "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/financials/" \
-H "Authorization: Bearer YOUR_TOKEN"
financials = requests.get(f"{BASE}/capital-receivers/{uuid}/financials/", headers=headers).json()
Example financials row:
{
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"uuid": "7f3a1b2c-4d5e-6f70-8192-a3b4c5d6e7f8",
"financial_year_end": "2023-12-31",
"total_revenue": 12450000.00,
"total_revenue_usd": 9410850.00,
"annual_total_revenue_yoy_growth_pct": 42.00,
"operating_revenue": 12450000.00,
"operating_revenue_usd": 9410850.00,
"annual_operating_revenue_yoy_growth_pct": 42.00,
"cogs": 4980000.00,
"cogs_usd": 3762780.00,
"annual_cogs_yoy_growth_pct": 31.00,
"gross_profit": 7470000.00,
"gross_profit_usd": 5645070.00,
"annual_gross_profit_yoy_growth_pct": null,
"total_expenses": 9200000.00,
"total_expenses_usd": 6952200.00,
"annual_total_expenses_yoy_growth_pct": null,
"earnings_before_tax": -1730000.00,
"earnings_before_tax_usd": -1307130.00,
"annual_earnings_before_tax_yoy_growth_pct": null,
"income_tax_expenses": null,
"income_tax_expenses_usd": null,
"annual_income_tax_expenses_yoy_growth_pct": null,
"earnings_after_tax": null,
"earnings_after_tax_usd": null,
"annual_earnings_after_tax_yoy_growth_pct": null,
"liabilities": 5630000.00,
"liabilities_usd": 4251030.00,
"annual_liabilities_yoy_growth_pct": null,
"reporting_currency": "SGD",
"notes": null,
"is_audited": true,
"audit_opinion": {"key": "audit_opinion_unqualified", "name": "Unqualified Opinion"},
"is_consolidated": false,
"is_restated": false
}
Every monetary and percentage value is a number or null, with growth percentages stated as percentages — 59.00 means +59%, not +0.59%. uuid identifies the financial record itself, and capital_receiver_uuid identifies the company — both are returned on the per-company endpoint as well as the batch endpoint.
Batch Financials via POST
Use POST /v3/partners/capital-receivers/financials/ (note: no {uuid} in the path) to pull financial records for many companies in one paginated request instead of calling the per-company .../{uuid}/financials/ endpoint once per company. The body must contain a non-empty capital_receiver_uuid in filter; up to 1,000 UUIDs are accepted per request. Each returned row carries a capital_receiver_uuid field so you can join it back to the company it belongs to.
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/financials/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "capital_receiver_uuid", "value": [
"c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"fee788ac-cffe-46f0-9bb5-fedb62992bd8"
]}
]
}
}'
Rows are ordered by most recent financial year end first and use exactly the same shape as the per-company financials endpoint — capital_receiver_uuid is present on both.
- A missing or empty
capital_receiver_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
News
Returns paginated news articles linked to this capital receiver.
curl "https://api.altdmp.io/v3/partners/capital-receivers/c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67/news/" \
-H "Authorization: Bearer YOUR_TOKEN"
news = requests.get(f"{BASE}/capital-receivers/{uuid}/news/", headers=headers).json()
Example response:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"uuid": "d4f2a891-1bc3-4e7d-9f32-abc123def456",
"date": "2022-12-13",
"headline": "ShopBack Secures $80M in Series F Funding Round",
"body": "ShopBack, Southeast Asia's leading cashback and rewards platform, has closed an $80M Series F round...",
"source_url": "https://techcrunch.com/2022/12/13/shopback-series-f/",
"type": {"key": "news_type_funding", "name": "Funding"}
}
]
}
News Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -date) |
limit | Results per page |
offset | Pagination offset |
Batch News via POST
Use POST /v3/partners/capital-receivers/news/ (note: no {uuid} in the path) to pull news articles for many companies in one paginated request instead of calling the per-company .../{uuid}/news/ endpoint once per company. The body must contain a non-empty capital_receiver_uuid in filter; up to 1,000 UUIDs are accepted per request. Each returned article carries a capital_receiver_uuid field so you can join it back to the company it belongs to.
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/news/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "capital_receiver_uuid", "value": [
"c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"fee788ac-cffe-46f0-9bb5-fedb62992bd8"
]}
]
}
}'
Articles are ordered most recent first. This is the one batch endpoint whose rows genuinely differ from the per-company shape: they add a capital_receiver_uuid join field that the per-company endpoint does not return.
{
"count": 4,
"next": null,
"previous": null,
"results": [
{
"uuid": "d4f2a891-1bc3-4e7d-9f32-abc123def456",
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"date": "2022-12-13",
"headline": "ShopBack Secures $80M in Series F Funding Round",
"body": "ShopBack, Southeast Asia's leading cashback and rewards platform, has closed an $80M Series F round...",
"source_url": "https://techcrunch.com/2022/12/13/shopback-series-f/",
"type": {"key": "news_type_funding", "name": "Funding"}
}
]
}
- A missing or empty
capital_receiver_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
Capital Allocators
Last updated: 25 August 2026
Capital allocators are the entities that deploy capital — VC firms, private equity firms, family offices, corporate venture arms, sovereign wealth funds, and more.
Endpoints
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/capital-allocators/ | Subscription required |
POST | /v3/partners/capital-allocators/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/investments/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/aum/ | Subscription required |
POST | /v3/partners/capital-allocators/aum/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/commitments/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/financials/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/captable/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/funds/ | Subscription required |
GET | /v3/partners/capital-allocators/{uuid}/news/ | Subscription required |
List Capital Allocators
curl "https://api.altdmp.io/v3/partners/capital-allocators/?search=Wavemaker" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
resp = requests.get(
f"{BASE}/capital-allocators/",
params={"search": "Wavemaker"},
headers=headers,
)
The
?search=parameter matches against the allocator’s owndisplay_nameand the linked legal entity’sdisplay_name.
One firm can appear as several rows. A firm holds a separate allocator profile per preferred allocation type, so a manager running equity and debt strategies returns two rows with two different
uuidvalues and the same underlyinglegal_entity.uuid. Deduplicate on the root UUID before counting firms or totaling amounts — see How Many Profiles Per Root Record.
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "f80754f5-16c7-4aac-9cab-4149285c7220",
"display_name": "Wavemaker Partners",
"description": "Wavemaker Partners is an early-stage VC firm investing across Southeast Asia and the US.",
"profile_type_key": "legal_entity",
"profile_type": "legalentity",
"legal_entity": {
"uuid": "b9ade3bb-05d1-4b0c-81e1-e91b8722b564",
"display_name": "Wavemaker Partners",
"year_founded": 2012,
"date_founded": "2012-03-08",
"date_founded_precision": "day",
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{
"reg_number": "201205678K",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
]
},
"person": null,
"types": [{"key": "ca_type_venture_capital_firm", "name": "Venture Capital Firm"}],
"preferred_allocation_type": {"key": "equity", "name": "Equity"},
"preferred_countries": [
{"iso_alpha3": "SGP", "name": "Singapore"},
{"iso_alpha3": "IDN", "name": "Indonesia"}
],
"preferred_themes": [{"key": "themes_payments", "name": "Payments"}],
"preferred_horizontals": [{"key": "horizontals_marketplaces", "name": "Marketplaces"}],
"preferred_business_models": [
{"key": "business_models_b2b", "name": "B2B (Business-to-Business)"}
],
"preferred_techs": [{"key": "techs_fintech", "name": "FinTech"}],
"preferred_fund_types": [
{"key": "venture_general_other", "name": "Venture - General / Other"}
],
"preferred_allocation_subtypes": [
{"key": "venture_capital", "name": "Venture Capital (VC)"}
],
"preferred_allocation_deal_types": [
{"key": "seed", "name": "Seed"},
{"key": "series_a", "name": "Series A"}
],
"preferred_industries": [
{"code": "09", "description": "Information and Communication"}
],
"cheque_size_avg": 3000000,
"cheque_size_min": 500000,
"cheque_size_max": 10000000,
"dry_powder": 85000000,
"median_valuation": 45000000,
"current_allocation": 115000000,
"target_allocation": 200000000,
"stated_count_of_investments": 38,
"is_open_to_first_time_fund": null,
"is_open_to_co_investment": true,
"has_preference_for_balanced_funds": null,
"has_preference_for_hybrid_funds": null,
"has_preference_for_special_situation_funds": null,
"has_preference_for_separate_account": null,
"last_updated_at": "2025-10-16T07:33:30Z"
}
]
}
profile_type_keytells you which oflegal_entity/personis populated:"legal_entity"fills thelegal_entityobject and leavespersonasnull;"person"does the reverse and returns{"uuid", "given_name", "family_name", "display_name", "location_country"}underperson. Branch onprofile_type_key, not on theprofile_typelabel. Thelegal_entityobject on the list response is the compact variant — the detail response returns a fuller one.
The self-declared boolean preferences (
is_open_to_*,has_preference_for_*) are nullable and commonlynull—nullmeans “not stated”, which is not the same asfalse.
List Query Parameters
| Parameter | Description |
|---|---|
search | Full-text search (see above) |
ordering | Sort field. Prefix with - for descending. Supported: display_name, cheque_size_min, cheque_size_max, cheque_size_avg, target_allocation, median_valuation, current_allocation, dry_powder, stated_count_of_investments, created_at, updated_at. An unsupported value returns 400 Bad Request listing the valid fields |
limit | Results per page |
offset | Pagination offset |
Advanced Filter (POST)
Use POST with a JSON body for complex filters. The body accepts only the filters object; pass search, ordering, limit, and offset as query parameters. filters cannot go the other way — a value in ?filters= returns 400 Bad Request on both GET and POST.
Operators, body shapes, and the supported filter field list for this endpoint are on the Filtering page. Note that
eq,ne,in, andninare case-sensitive, and that an unrecognizedopis silently treated aseqrather than rejected.
# VC firms in Singapore that invest at Seed and Series A
curl -X POST https://api.altdmp.io/v3/partners/capital-allocators/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"},
{"op": "in", "field": "preferred_allocation_deal_types_names", "value": ["Seed", "Series A"]}
]
}
}'
resp = requests.post(
f"{BASE}/capital-allocators/",
headers=headers,
json={
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"},
{"op": "in", "field": "preferred_allocation_deal_types_names",
"value": ["Seed", "Series A"]},
]
}
},
)
Common Filter Fields
| Field | Type | Example |
|---|---|---|
domicile_country_iso_alpha3 | string | "SGP" |
domicile_country_name | string | "Singapore" |
headquarters_country_iso_alpha3 | string | "SGP" |
headquarters_country_name | string | "Singapore" |
preferred_allocation_deal_types_names | string | "Seed" |
preferred_allocation_deal_types_keys | string | "seed" |
types_names / types_keys | string | "Venture Capital Firm" / "ca_type_venture_capital_firm" |
preferred_allocation_type_name / preferred_allocation_type_key | string | "Equity" / "equity" |
preferred_allocation_subtypes_names / preferred_allocation_subtypes_keys | string | "Venture Capital (VC)" / "venture_capital" |
preferred_countries_names / preferred_countries_iso_alpha3 | string | "Singapore" / "SGP" |
preferred_themes_names / preferred_themes_keys | string | "Payments" / "themes_payments" |
preferred_horizontals_names / preferred_horizontals_keys | string | "Marketplaces" / "horizontals_marketplaces" |
preferred_business_models_names / preferred_business_models_keys | string | "B2B (Business-to-Business)" / "business_models_b2b" |
preferred_techs_names / preferred_techs_keys | string | "FinTech" / "techs_fintech" |
preferred_fund_types_names / preferred_fund_types_keys | string | "Venture - General / Other" / "venture_general_other" |
preferred_industries_codes | string | "09" |
cheque_size_avg / cheque_size_min / cheque_size_max | number | 3000000 |
dry_powder / median_valuation / current_allocation / target_allocation | number | 85000000 |
stated_count_of_investments | integer | 38 |
is_open_to_first_time_fund / is_open_to_co_investment / has_preference_for_balanced_funds / has_preference_for_hybrid_funds / has_preference_for_special_situation_funds / has_preference_for_separate_account | boolean | true |
display_name / description | string | "Meridian" |
Multi-value preference fields are plural. The name is the plural response field plus
_namesor_keys—preferred_allocation_deal_types_names, notpreferred_allocation_deal_type_name. Singular forms return400 Bad Request. The one exception is the single-valuedpreferred_allocation_type, which takespreferred_allocation_type_name/preferred_allocation_type_key.
Geography filters (
domicile_country_*,headquarters_country_*) resolve through the allocator’s linked legal entity. Capital allocators backed by aPerson(rather than a legal entity) returnnullfor these fields and are excluded when a country filter is applied.
Get Capital Allocator Detail
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/" \
-H "Authorization: Bearer YOUR_TOKEN"
uuid = "f80754f5-16c7-4aac-9cab-4149285c7220"
detail = requests.get(f"{BASE}/capital-allocators/{uuid}/", headers=headers).json()
The detail response returns every field from the list response, with a fuller legal_entity object, plus twenty additional fields covering AUM, stated preferences not on the list, and the actual_* behavioural rollups.
{
"uuid": "f80754f5-16c7-4aac-9cab-4149285c7220",
"display_name": "Meridian Ventures Pte. Ltd.",
"description": "Meridian Ventures is a Singapore-based early-stage VC firm investing across Southeast Asia, with a focus on B2B SaaS, FinTech, and HealthTech.",
"profile_type_key": "legal_entity",
"profile_type": "legalentity",
"legal_entity": {
"uuid": "b9ade3bb-05d1-4b0c-81e1-e91b8722b564",
"display_name": "Meridian Ventures Pte. Ltd.",
"description": "Meridian Ventures is a Singapore-based early-stage VC firm.",
"year_founded": 2013,
"date_founded": "2013-06-14",
"date_founded_precision": "day",
"is_female_founder": true,
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"headquarters": {
"country_name": "Singapore",
"country_iso_alpha3": "SGP",
"state_name": null,
"city_name": "Singapore"
},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{
"reg_number": "201316157E",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
],
"alternate_names": [
{"name": "Meridian Ventures", "type": "Other", "type_key": "alt_name_other"}
],
"website_url": "https://www.meridian.vc",
"email": "ir@meridian.vc",
"phone": null,
"founders": [{"uuid": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e", "name": "Priya Raman"}],
"directors": [{"uuid": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "name": "Jia Wei Tan"}],
"auditors": [{"uuid": "ad9be164-4e19-4822-987e-54efe73d8974", "name": "Baker Tilly LSC"}]
},
"person": null,
"types": [{"key": "ca_type_venture_capital_firm", "name": "Venture Capital Firm"}],
"preferred_allocation_type": {"key": "equity", "name": "Equity"},
"preferred_countries": [
{"iso_alpha3": "IDN", "name": "Indonesia"},
{"iso_alpha3": "SGP", "name": "Singapore"},
{"iso_alpha3": "VNM", "name": "Vietnam"}
],
"preferred_themes": [
{"key": "themes_payments", "name": "Payments"},
{"key": "themes_business_applications_saas", "name": "Business Applications / SaaS"}
],
"preferred_horizontals": [{"key": "horizontals_marketplaces", "name": "Marketplaces"}],
"preferred_business_models": [
{"key": "business_models_b2b", "name": "B2B (Business-to-Business)"}
],
"preferred_techs": [{"key": "techs_fintech", "name": "FinTech"}],
"preferred_fund_types": [
{"key": "venture_general_other", "name": "Venture - General / Other"}
],
"preferred_allocation_subtypes": [
{"key": "venture_capital", "name": "Venture Capital (VC)"}
],
"preferred_allocation_deal_types": [
{"key": "seed", "name": "Seed"},
{"key": "series_a", "name": "Series A"},
{"key": "series_b", "name": "Series B"}
],
"preferred_industries": [
{"code": "09", "description": "Information and Communication"}
],
"cheque_size_avg": 3000000,
"cheque_size_min": 500000,
"cheque_size_max": 10000000,
"dry_powder": 85000000,
"median_valuation": 45000000,
"current_allocation": 115000000,
"target_allocation": 200000000,
"stated_count_of_investments": 38,
"is_open_to_first_time_fund": null,
"is_open_to_co_investment": true,
"has_preference_for_balanced_funds": null,
"has_preference_for_hybrid_funds": null,
"has_preference_for_special_situation_funds": null,
"has_preference_for_separate_account": null,
"last_updated_at": "2025-10-16T07:33:30Z",
"preferred_other_preferences": null,
"route_to_market": ["Direct Deals"],
"current_allocation_date": null,
"latest_aum": {
"uuid": "da38f125-485d-45ca-b637-73a71f31c8c1",
"aum_value_date": "2024-12-31",
"aum_value": 200000000.00,
"aum_value_usd": 200000000.00,
"reporting_currency": {"iso_code": "USD", "name": "US Dollar"}
},
"actual_count_of_investments": 52,
"actual_allocation_types": ["Commitment", "Equity"],
"actual_allocation_subtypes": ["Commitment", "Venture Capital (VC)"],
"actual_allocation_deal_types": ["Pre-Seed", "Seed", "Series A", "Series B", "Series C"],
"actual_fund_types": ["Pre-Seed", "Seed", "Series A", "Series B"],
"actual_themes": ["Business Applications / SaaS", "Payments"],
"actual_horizontals": ["Customer Stack", "Marketplaces"],
"actual_business_models": ["B2B (Business-to-Business)", "B2C (Business-to-Consumer)"],
"actual_techs": ["FinTech", "RetailTech"],
"actual_industries": [
{"code": "0602", "description": "Retail Trade (Except Vehicles)"},
{"code": "09", "description": "Information and Communication"}
],
"actual_countries": ["Indonesia", "Malaysia", "Singapore"],
"actual_min_investment_amount_usd": 250000.0,
"actual_max_investment_amount_usd": 8500000.0
}
Profile Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Capital allocator profile UUID |
display_name | string | Firm or individual name |
profile_type_key | string | "legal_entity" or "person" — branch on this. Tells you which of the legal_entity / person objects is populated; the other is null |
profile_type | string | Human-readable label for the same thing, currently "legalentity" / "person". Presentation only — do not branch on it, and see Keys and Display Values |
legal_entity | object, nullable | Underlying registered company. See Data Model |
person | object, nullable | uuid, given_name, family_name, display_name, location_country — for person-backed allocators |
types | array | Firm-type classification (e.g. Venture Capital Firm, Family Office) |
preferred_allocation_type | object, nullable | The asset class this profile covers, not the firm’s only one. A firm allocating both equity and debt has a separate allocator profile per allocation type, each with its own UUID — see How Many Profiles Per Root Record |
preferred_allocation_deal_types | array | Stated preferred deal stages |
preferred_allocation_subtypes | array | Stated preferred allocation subtypes |
preferred_countries | array | Target geographies (iso_alpha3 + name) |
preferred_themes | array | Target investment themes |
preferred_horizontals | array | Target horizontal tech categories |
preferred_business_models | array | Target business models |
preferred_techs | array | Target technology focus areas |
preferred_fund_types | array | Fund types the firm allocates to |
preferred_industries | array | Target industries (code + description) |
preferred_other_preferences | string, nullable | Free-text preferences that don’t fit the structured fields |
route_to_market | array of strings, nullable | How the firm deploys, e.g. ["Direct Deals"] |
cheque_size_avg / cheque_size_min / cheque_size_max | integer, nullable | Cheque size in USD |
dry_powder | integer, nullable | Undeployed capital in USD |
median_valuation | integer, nullable | Median entry valuation in USD |
current_allocation / target_allocation | integer, nullable | Capital deployed and target total, in USD |
current_allocation_date | date string, nullable | As-of date for current_allocation |
stated_count_of_investments | integer, nullable | Self-stated portfolio company count |
is_open_to_first_time_fund / is_open_to_co_investment / has_preference_for_balanced_funds / has_preference_for_hybrid_funds / has_preference_for_special_situation_funds / has_preference_for_separate_account | boolean, nullable | Self-declared preferences. null means “not stated” — treat it as unknown, not as false |
latest_aum | object, nullable | Most recent AUM record: uuid, aum_value_date, aum_value, aum_value_usd, reporting_currency |
actual_count_of_investments | integer | Actual count from transaction records |
actual_allocation_types / actual_allocation_subtypes / actual_allocation_deal_types / actual_fund_types / actual_themes / actual_horizontals / actual_business_models / actual_techs | array of strings | Classifications the firm has actually transacted in — display names, not keys, and flat strings rather than {key, name} objects |
actual_industries | array | Industries actually invested in — {code, description} objects, unlike the other actual_* arrays |
actual_countries | array of strings | Countries of portfolio companies as country names (e.g. "Singapore"), not ISO alpha-3 codes |
actual_min_investment_amount_usd / actual_max_investment_amount_usd | number, nullable | Smallest and largest recorded investment in USD |
actual_*fields are derived from real transaction records on the platform.preferred_*fields are self-declared by the firm. Compare the two to assess stated vs. actual investment behaviour.
The two families use different value shapes.
preferred_*arrays return{key, name}(or{code, description}for industries) so they can be matched against reference data. Mostactual_*arrays return bare display-name strings with no key — match them onname, notkey.
Investments
Returns the portfolio — all companies this allocator has invested in.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/investments/" \
-H "Authorization: Bearer YOUR_TOKEN"
investments = requests.get(
f"{BASE}/capital-allocators/{uuid}/investments/", headers=headers
).json()
Example response row:
{
"count": 52,
"next": "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-.../investments/?limit=20&offset=20",
"previous": null,
"results": [
{
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity_uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"capital_receiver_name": "Shopback",
"shares_issued": 1500000.0,
"shares_bought_secondary": 0.0,
"shares_sold": 250000.0,
"shares_currently_held": 1250000.0,
"total_invested_usd": 7500000.00,
"first_investment_date": "2019-04-30",
"latest_investment_date": "2022-03-01"
}
]
}
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -latest_investment_date) |
limit | Results per page |
offset | Pagination offset |
AUM History
Returns a time series of assets under management records.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/aum/" \
-H "Authorization: Bearer YOUR_TOKEN"
aum = requests.get(f"{BASE}/capital-allocators/{uuid}/aum/", headers=headers).json()
Example response:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"uuid": "da38f125-485d-45ca-b637-73a71f31c8c1",
"aum_value_date": "2024-12-31",
"aum_value": 270000000.00,
"aum_value_usd": 200000000.00,
"reporting_currency": {"iso_code": "SGD", "name": "Singapore Dollar"}
}
]
}
| Field | Type | Description |
|---|---|---|
uuid | string | UUID of the AUM record |
aum_value_date | date string | As-of date |
aum_value | number | Amount in the reporting currency |
aum_value_usd | number | Same amount normalized to USD |
reporting_currency | object, nullable | iso_code and name of the currency aum_value is denominated in |
aum_valueis in the reporting currency andaum_value_usdis normalized — they are equal only whenreporting_currency.iso_codeis"USD".
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -aum_value_date) |
limit | Results per page |
offset | Pagination offset |
Batch AUM via POST
Use POST /v3/partners/capital-allocators/aum/ (note: no {uuid} in the path) to pull AUM history for many allocators in one paginated request instead of calling the per-allocator .../{uuid}/aum/ endpoint once per allocator. The body must contain a non-empty capital_allocator_uuid in filter; up to 1,000 UUIDs are accepted per request. Each returned record carries a capital_allocator_uuid field so you can join it back to the allocator it belongs to.
curl -X POST "https://api.altdmp.io/v3/partners/capital-allocators/aum/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "capital_allocator_uuid", "value": [
"f80754f5-16c7-4aac-9cab-4149285c7220",
"a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
]}
]
}
}'
Records are ordered by most recent AUM value date first and use the same shape as the per-allocator AUM endpoint, plus the capital_allocator_uuid join field that the per-allocator endpoint does not return.
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "da38f125-485d-45ca-b637-73a71f31c8c1",
"capital_allocator_uuid": "f80754f5-16c7-4aac-9cab-4149285c7220",
"aum_value_date": "2024-12-31",
"aum_value": 270000000.00,
"aum_value_usd": 200000000.00,
"reporting_currency": {"iso_code": "SGD", "name": "Singapore Dollar"}
}
]
}
- A missing or empty
capital_allocator_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
LP Commitments
Returns commitments made by this allocator to funds (i.e. where this allocator acts as an LP).
Access to this endpoint is subject to your subscription.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/commitments/" \
-H "Authorization: Bearer YOUR_TOKEN"
commitments = requests.get(
f"{BASE}/capital-allocators/{uuid}/commitments/", headers=headers
).json()
Each row is one commitment transaction by this allocator, with the receiving fund nested under fund. There is no buyer / seller pair here — the allocator is implied by the path, and the counterparty is fund. (The mirror-image feed, LP commitments into a fund, has a different shape again.)
Example response:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uuid": "a8c7be86-7b7b-480a-a742-adbf94260b6a",
"fund": {
"uuid": "4ee71a3c-3926-4002-992a-4032bc93a8ea",
"display_name": "Sembrani Nusantara",
"vintage_year": 2020,
"status": {"key": "fund_status_closed", "name": "Closed"}
},
"date": "2022-03-15",
"allocation_type": {"key": "allocation_type_commitment", "name": "Commitment"},
"allocation_subtype": {"key": "allocation_subtype_commitment", "name": "Commitment"},
"provenance": {
"key": "deal_txn_provenance_filed_regulator",
"name": "Filed with Regulator"
},
"transaction_currency": {"iso_code": "USD", "name": "US Dollar"},
"cash_value_transacted": 25000000.00,
"cash_value_transacted_usd": 25000000.00
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Commitment transaction UUID |
fund | object, nullable | The fund receiving the commitment: uuid, display_name, vintage_year, status. null when the receiving legal entity has no fund profile — use fund.uuid with /funds/{uuid}/ |
date | date string, nullable | Commitment date. Frequently null, since regulator filings often carry no date |
allocation_type / allocation_subtype | object, nullable | {key, name} classification of the commitment |
provenance | object, nullable | Where the record came from, e.g. Filed with Regulator, Filed via FOIA, Reported |
transaction_currency | object, nullable | iso_code and name of the currency cash_value_transacted is denominated in |
cash_value_transacted | number, nullable | Committed amount in the transaction currency |
cash_value_transacted_usd | number, nullable | Same amount normalized to USD |
The amount fields here are named
cash_value_transacted*, notinvestment_amount_usd. Sort with?ordering=-dateand expect a long tail ofnulldates and amounts, since regulator-filed commitments are often disclosed without either.
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -date) |
limit | Results per page |
offset | Pagination offset |
Financials
Returns historical financial records for this capital allocator’s underlying legal entity, ordered by most recent financial year end first. Each row includes year-over-year growth annotations.
Returns an empty list for allocators backed by a Person rather than a legal entity.
Growth-% values are capped at ±1000%. Each
annual_*_yoy_growth_pctfield returnsnullwhen the computed change exceeds +1000% or falls below −1000%; values at exactly ±1000% are retained. Anulltherefore means the value is missing, has a zero denominator, or is out of bounds.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/financials/" \
-H "Authorization: Bearer YOUR_TOKEN"
financials = requests.get(
f"{BASE}/capital-allocators/{uuid}/financials/", headers=headers
).json()
Example financials row:
{
"capital_receiver_uuid": null,
"uuid": "5c8d9e0f-1a2b-3c4d-5e6f-708192a3b4c5",
"financial_year_end": "2023-12-31",
"total_revenue": 246422.00,
"total_revenue_usd": 186310.00,
"annual_total_revenue_yoy_growth_pct": 59.00,
"operating_revenue": 246422.00,
"operating_revenue_usd": 186310.00,
"annual_operating_revenue_yoy_growth_pct": 59.00,
"cogs": null,
"cogs_usd": null,
"annual_cogs_yoy_growth_pct": null,
"gross_profit": null,
"gross_profit_usd": null,
"annual_gross_profit_yoy_growth_pct": null,
"total_expenses": null,
"total_expenses_usd": null,
"annual_total_expenses_yoy_growth_pct": null,
"earnings_before_tax": -970799.00,
"earnings_before_tax_usd": -733918.00,
"annual_earnings_before_tax_yoy_growth_pct": null,
"income_tax_expenses": null,
"income_tax_expenses_usd": null,
"annual_income_tax_expenses_yoy_growth_pct": null,
"earnings_after_tax": null,
"earnings_after_tax_usd": null,
"annual_earnings_after_tax_yoy_growth_pct": null,
"liabilities": 832063.00,
"liabilities_usd": 629187.00,
"annual_liabilities_yoy_growth_pct": null,
"reporting_currency": "SGD",
"notes": null,
"is_audited": true,
"audit_opinion": {"key": "audit_opinion_unqualified", "name": "Unqualified Opinion"},
"is_consolidated": false,
"is_restated": false
}
Rows carry the same fields as the capital receiver financials endpoint, including a uuid for the financial record itself and a capital_receiver_uuid. Here capital_receiver_uuid is populated only when the same company also appears as a capital receiver; otherwise it is null. Every monetary and percentage value is a number or null. Growth percentages are percentages — 59.00 means +59%, not +0.59%.
Financials Query Parameters
| Parameter | Description |
|---|---|
limit | Results per page |
offset | Pagination offset |
Cap Table
Returns the shareholding structure for this capital allocator’s underlying legal entity. The response shape depends on captable_source.type.
Returns an empty response for allocators backed by a Person.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/captable/" \
-H "Authorization: Bearer YOUR_TOKEN"
captable = requests.get(
f"{BASE}/capital-allocators/{uuid}/captable/", headers=headers
).json()
source_type = captable["captable_source"]["type"] # "managed" or "snapshot"
The response structure mirrors the Capital Receivers cap table — check captable_source.type to determine which fields are present.
Managed Cap Table Response
When captable_source.type is "managed", the cap table is derived from transaction records. Share counts and investment amounts are available.
{
"count": 6,
"next": null,
"previous": null,
"results": [
{
"shareholder": {
"uuid": "37c44afc-e55e-420c-bb2a-f9225a0d1c8e",
"name": "Sequoia Capital Southeast Asia Fund III",
"type_key": "fund",
"type": "FundProfile"
},
"shares_issued_absolute": 2000000,
"shares_issued_aggregate": 2400000,
"shares_bought_secondary_absolute": 0,
"shares_bought_secondary_aggregate": 0,
"shares_sold_absolute": 0,
"shares_sold_aggregate": 0,
"total_invested_usd_absolute": 12000000.0,
"total_invested_usd_aggregate": 14400000.0,
"is_held_in_treasury": false,
"shares_currently_held_absolute": 2000000,
"shares_currently_held_aggregate": 2400000,
"percentage_held_absolute": 18.50,
"percentage_held_aggregate": 22.20,
"holding_value_usd": 24000000.00,
"child_entities_count": 1,
"child_entities": [
{
"shareholder": {
"uuid": "8b7a6c5d-4e3f-2a1b-0c9d-8e7f6a5b4c3d",
"name": "Sequoia SEA III SPV 1",
"type_key": "legal_entity",
"type": "LegalEntity"
},
"shares_issued_absolute": 400000,
"shares_issued_aggregate": 400000,
"shares_bought_secondary_absolute": 0,
"shares_bought_secondary_aggregate": 0,
"shares_sold_absolute": 0,
"shares_sold_aggregate": 0,
"total_invested_usd_absolute": 2400000.0,
"total_invested_usd_aggregate": 2400000.0,
"is_held_in_treasury": false,
"shares_currently_held_absolute": 400000,
"shares_currently_held_aggregate": 400000,
"percentage_held_absolute": 3.70,
"percentage_held_aggregate": 3.70,
"holding_value_usd": 4000000.00,
"child_entities_count": 0,
"child_entities": []
}
]
}
],
"captable_source": {"type": "managed"},
"as_of_date": "2026-05-08",
"aggregations": {
"shares_issued_aggregate": 10800000,
"shares_bought_secondary_aggregate": 0,
"shares_sold_aggregate": 0,
"total_invested_usd_aggregate": 64800000.00,
"shares_currently_held_aggregate": 10800000,
"percentage_held_aggregate": 100.00,
"holding_value_usd": 108000000.00
}
}
The fields are identical to the capital receiver cap table — see there for what each one means. In particular, join shareholder.uuid by shareholder.type_key rather than by the type label, aggregations keys are *_aggregate names rather than total_shares_issued / total_shares_held, and child_entities rows nest with the same shape as top-level rows.
Snapshot Cap Table Response
When captable_source.type is "snapshot", the cap table is sourced from a shareholder-register filing. Investment amounts are not available.
{
"count": 4,
"next": null,
"previous": null,
"results": [
{
"shareholder": {
"uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"name": "GIC Private Limited",
"type_key": "legal_entity",
"type": "LegalEntity"
},
"number_of_shares": 3500000,
"percentage_held": 32.40000,
"is_former_shareholder": false,
"start_date": "2020-06-01",
"end_date": null
}
],
"captable_source": {"type": "snapshot"},
"as_of_date": "2024-12-31",
"aggregations": null
}
When the allocator’s legal entity has no cap table at all — and for person-backed allocators, which have no legal entity — the pagination keys are omitted and the response is just
{"captable_source": {...}, "as_of_date": null, "results": [], "aggregations": null}.
Funds
Returns a paginated list of funds managed by this capital allocator.
Returns an empty list for allocators backed by a Person. To retrieve investments for a specific fund, use /partners/funds/{uuid}/investments/.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/funds/" \
-H "Authorization: Bearer YOUR_TOKEN"
funds = requests.get(
f"{BASE}/capital-allocators/{uuid}/funds/", headers=headers
).json()
Example response:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"legal_entity": {
"uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"display_name": "Sequoia Capital SEA Fund III",
"year_founded": 2021,
"date_founded": "2021-02-11",
"date_founded_precision": "day",
"domicile_country": {"iso_alpha3": "CYM", "name": "Cayman Islands"},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{"reg_number": "MC-987321", "authority_type": null, "authority_name": null}
]
},
"display_name": "Sequoia Capital SEA Fund III",
"description": "Southeast Asia-focused growth equity fund",
"fund_managers": [
{"uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012", "display_name": "Sequoia Capital Southeast Asia"}
],
"status": {"key": "fund_status_closed", "name": "Closed"},
"vintage_year": 2021,
"is_raising_now": false,
"last_updated_at": "2025-11-15T08:22:31Z"
},
{
"uuid": "d4e5f6a7-b8c9-0123-defa-234567890123",
"legal_entity": {
"uuid": "e5f6a7b8-c9d0-1234-efab-345678901234",
"display_name": "Sequoia Capital SEA Fund IV",
"year_founded": null,
"date_founded": null,
"date_founded_precision": null,
"domicile_country": null,
"trading_status": null,
"registration_numbers": []
},
"display_name": "Sequoia Capital SEA Fund IV",
"description": null,
"fund_managers": [
{"uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012", "display_name": "Sequoia Capital Southeast Asia"}
],
"status": {"key": "fund_status_raising", "name": "Raising"},
"vintage_year": 2024,
"is_raising_now": true,
"last_updated_at": "2026-03-01T14:10:00Z"
}
]
}
Rows use the same shape as GET /partners/funds/. The nested legal_entity here is the compact variant (no headquarters, no description) — fetch /funds/{uuid}/ for the full object.
Funds Query Parameters
| Parameter | Description |
|---|---|
limit | Results per page |
offset | Pagination offset |
News
Returns paginated news articles linked to this capital allocator’s underlying legal entity.
Returns an empty list for allocators backed by a Person.
curl "https://api.altdmp.io/v3/partners/capital-allocators/f80754f5-16c7-4aac-9cab-4149285c7220/news/" \
-H "Authorization: Bearer YOUR_TOKEN"
news = requests.get(
f"{BASE}/capital-allocators/{uuid}/news/", headers=headers
).json()
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "e7a3b2c1-...",
"date": "2024-06-01",
"headline": "Meridian Ventures Closes $200M Fund II",
"body": "Meridian Ventures has held the final close of its second Southeast Asia-focused fund...",
"source_url": "https://dealstreetasia.com/...",
"type": {"key": "news_type_closing_fund", "name": "Closing of a Fund"}
}
]
}
News Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -date) |
limit | Results per page |
offset | Pagination offset |
Funds
Last updated: 25 August 2026
Fund profiles represent individual fund vehicles — each managed by one or more capital allocators. This covers venture capital funds, private equity funds, and other structured vehicles.
Endpoints
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/funds/ | Subscription required |
POST | /v3/partners/funds/ | Subscription required |
GET | /v3/partners/funds/{uuid}/ | Subscription required |
GET | /v3/partners/funds/{uuid}/performance/ | Subscription required |
POST | /v3/partners/funds/performance/ | Subscription required |
GET | /v3/partners/funds/{uuid}/aum/ | Subscription required |
GET | /v3/partners/funds/{uuid}/commitments/ | Subscription required |
GET | /v3/partners/funds/{uuid}/investments/ | Subscription required |
GET | /v3/partners/funds/{uuid}/news/ | Subscription required |
List Funds
curl "https://api.altdmp.io/v3/partners/funds/?search=Wavemaker" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
resp = requests.get(
f"{BASE}/funds/",
params={"search": "Wavemaker"},
headers=headers,
)
Example response:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uuid": "73541611-0738-46fb-abbd-7e9dcf74b00c",
"legal_entity": {
"uuid": "c7cccf8b-93ff-4fbe-b979-a3372ea177f7",
"display_name": "Wavemaker Pacific 1 Ltd",
"year_founded": 2017,
"date_founded": "2017-03-22",
"date_founded_precision": "day",
"domicile_country": {"iso_alpha3": "CYM", "name": "Cayman Islands"},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{"reg_number": "MC-321654", "authority_type": null, "authority_name": null}
]
},
"display_name": "Wavemaker Pacific 1",
"description": "Wavemaker Pacific 1 is a $66M early-stage fund focused on B2B and deep tech across Southeast Asia.",
"fund_managers": [
{"uuid": "f80754f5-16c7-4aac-9cab-4149285c7220", "display_name": "Wavemaker Partners"}
],
"status": {"key": "fund_status_closed", "name": "Closed"},
"vintage_year": 2017,
"is_raising_now": false,
"last_updated_at": "2025-10-16T07:33:30Z"
}
]
}
The list
legal_entityhas noheadquarters. It is the compact variant:uuid,display_name,year_founded,date_founded,date_founded_precision,domicile_country,trading_status,registration_numbers. Geography beyond domicile — includingheadquarters— only appears on the detail response, even thoughheadquarters_country_iso_alpha3is filterable on the list.
status,vintage_year, and every nestedlegal_entitysub-object are nullable. Many fund records in the data set are thinly populated, so expectnullforstatus,vintage_year,domicile_country, andtrading_status, and[]forfund_managers.
List Query Parameters
| Parameter | Description |
|---|---|
search | Full-text search on fund and fund manager names |
ordering | Sort field. Prefix with - for descending. Supported: display_name, vintage_year, term_years, created_at, updated_at. An unsupported value returns 400 Bad Request listing the valid fields |
limit | Results per page |
offset | Pagination offset |
Advanced Filter (POST)
Use POST with a JSON body for complex filters on fund attributes. The body accepts only the filters object; pass search, ordering, limit, and offset as query parameters. filters cannot go the other way — a value in ?filters= returns 400 Bad Request on both GET and POST.
Operators, body shapes, and the supported filter field list for this endpoint are on the Filtering page. Note that
eq,ne,in, andninare case-sensitive, and that an unrecognizedopis silently treated aseqrather than rejected.
# Cayman-domiciled funds targeting Southeast Asia at Series A or Series B
curl -X POST https://api.altdmp.io/v3/partners/funds/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "CYM"},
{"op": "in", "field": "preferred_countries_iso_alpha3", "value": ["SGP", "IDN", "MYS", "PHL", "THA", "VNM"]},
{"op": "in", "field": "preferred_allocation_types_names", "value": ["Series A", "Series B"]}
]
}
}'
# Funds currently raising, domiciled in Singapore
curl -X POST https://api.altdmp.io/v3/partners/funds/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "SGP"},
{"op": "eq", "field": "status_key", "value": "fund_status_raising"}
]
}
}'
# Cayman-domiciled funds targeting SEA at Series A/B
resp = requests.post(
f"{BASE}/funds/",
headers=headers,
json={
"filters": {
"all": [
{"op": "eq", "field": "domicile_country_iso_alpha3", "value": "CYM"},
{"op": "in", "field": "preferred_countries_iso_alpha3", "value": ["SGP", "IDN", "MYS", "PHL", "THA", "VNM"]},
{"op": "in", "field": "preferred_allocation_types_names", "value": ["Series A", "Series B"]},
]
}
},
)
Common Filter Fields
| Field | Type | Example |
|---|---|---|
domicile_country_iso_alpha3 | string | "CYM" |
domicile_country_name | string | "Cayman Islands" |
headquarters_country_iso_alpha3 | string | "SGP" |
headquarters_country_name | string | "Singapore" |
status_key | string | "fund_status_raising" |
vintage_year | integer | 2020 |
date_founded | date string | "2014-04-01" |
preferred_countries_iso_alpha3 | string | "SGP" |
preferred_allocation_types_names | string | "Series A" |
date_foundedfilters on the fund’s full founding date and supportsgte,lte,range, andeq. Thelegal_entityobject also exposesdate_foundedanddate_founded_precision("year","month", or"day") alongside the retained year-onlyyear_founded.
Get Fund Detail
# Wavemaker Pacific 1
curl "https://api.altdmp.io/v3/partners/funds/73541611-0738-46fb-abbd-7e9dcf74b00c/" \
-H "Authorization: Bearer YOUR_TOKEN"
uuid = "73541611-0738-46fb-abbd-7e9dcf74b00c"
fund = requests.get(f"{BASE}/funds/{uuid}/", headers=headers).json()
The detail response returns everything from the list response — with the fuller legal_entity object — plus terms, fees, preference arrays, fund size, and eight classification flags.
{
"uuid": "73541611-0738-46fb-abbd-7e9dcf74b00c",
"legal_entity": {
"uuid": "c7cccf8b-93ff-4fbe-b979-a3372ea177f7",
"display_name": "Meridian SEA Fund II Ltd",
"description": "Cayman-domiciled fund vehicle managed by Meridian Ventures.",
"year_founded": 2022,
"date_founded": "2022-01-18",
"date_founded_precision": "day",
"is_female_founder": null,
"domicile_country": {"iso_alpha3": "CYM", "name": "Cayman Islands"},
"headquarters": {
"country_name": "Singapore",
"country_iso_alpha3": "SGP",
"state_name": null,
"city_name": "Singapore"
},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{"reg_number": "MC-321654", "authority_type": null, "authority_name": null}
],
"alternate_names": [
{"name": "Meridian SEA II", "type": "Other", "type_key": "alt_name_other"}
],
"website_url": null,
"email": null,
"phone": null,
"founders": [],
"directors": [{"uuid": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "name": "Jia Wei Tan"}],
"auditors": [{"uuid": "ad9be164-4e19-4822-987e-54efe73d8974", "name": "Baker Tilly LSC"}]
},
"display_name": "Meridian SEA Fund II",
"description": "Meridian SEA Fund II is a $200M Series A and Series B fund focused on B2B SaaS and FinTech across Southeast Asia.",
"fund_managers": [
{"uuid": "f80754f5-16c7-4aac-9cab-4149285c7220", "display_name": "Meridian Ventures Pte. Ltd."}
],
"status": {"key": "fund_status_closed", "name": "Closed"},
"vintage_year": 2022,
"is_raising_now": false,
"last_updated_at": "2025-10-16T07:33:30Z",
"term_years": 10,
"structure": "Limited Partnership",
"currency": {"iso_code": "USD", "name": "US Dollar"},
"target_close_date": "2022-06-30",
"preferred_countries": [
{"iso_alpha3": "SGP", "name": "Singapore"},
{"iso_alpha3": "IDN", "name": "Indonesia"},
{"iso_alpha3": "VNM", "name": "Vietnam"}
],
"preferred_themes": [
{"key": "themes_payments", "name": "Payments"},
{"key": "themes_business_applications_saas", "name": "Business Applications / SaaS"}
],
"preferred_horizontals": [{"key": "horizontals_marketplaces", "name": "Marketplaces"}],
"preferred_business_models": [
{"key": "business_models_b2b", "name": "B2B (Business-to-Business)"}
],
"preferred_techs": [{"key": "techs_fintech", "name": "FinTech"}],
"preferred_allocation_types": [{"key": "equity", "name": "Equity"}],
"preferred_allocation_subtypes": [
{"key": "venture_capital", "name": "Venture Capital (VC)"}
],
"preferred_allocation_deal_types": [
{"key": "series_a", "name": "Series A"},
{"key": "series_b", "name": "Series B"}
],
"preferred_industries": [
{"code": "09", "description": "Information and Communication"}
],
"preferred_other_preferences": null,
"latest_fund_size": {
"uuid": "da38f125-485d-45ca-b637-73a71f31c8c1",
"aum_value_date": "2024-12-31",
"aum_value": 200000000.00,
"aum_value_usd": 200000000.00,
"reporting_currency": {"iso_code": "USD", "name": "US Dollar"}
},
"is_first_time_fund": false,
"is_foia_reportable": null,
"is_captive_fund": null,
"is_single_deal_fund": false,
"is_continuation_fund": false,
"is_hybrid_fund": null,
"is_balanced_fund": null,
"is_special_situation_fund": null,
"management_fee_percentage": 2.00,
"gp_commitment_percentage": 2.00,
"hurdle_percentage": 8.00,
"carry_percentage": 20.00
}
Fund Profile Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Fund profile UUID |
legal_entity | object, nullable | The fund’s registered vehicle. See Data Model |
display_name | string | Fund name |
description | string, nullable | Fund description |
fund_managers | array | Managing capital allocator(s) — uuid + display_name. Use the uuid with /capital-allocators/{uuid}/ |
status | object, nullable | Fund lifecycle status, e.g. {"key": "fund_status_closed", "name": "Closed"} |
vintage_year | integer, nullable | Year the fund was established / first close |
is_raising_now | boolean, nullable | Currently in fundraise |
term_years | integer, nullable | Fund term in years |
structure | string, nullable | Free-text legal structure, e.g. "Limited Partnership", "Commingled", "Closed-end", "Separately Managed", "Variable Capital Company". Not a {key, name} object and not drawn from a fixed enum |
currency | object, nullable | The fund’s denomination currency: iso_code + name |
target_close_date | date string, nullable | Target final-close date |
preferred_countries / preferred_themes / preferred_horizontals / preferred_business_models / preferred_techs / preferred_allocation_types / preferred_allocation_subtypes / preferred_allocation_deal_types / preferred_industries | array | Stated mandate. Empty arrays when nothing is declared |
preferred_other_preferences | string, nullable | Free-text mandate notes |
latest_fund_size | object, nullable | Most recent AUM record: uuid, aum_value_date, aum_value, aum_value_usd, reporting_currency |
is_first_time_fund / is_foia_reportable / is_captive_fund / is_single_deal_fund / is_continuation_fund / is_hybrid_fund / is_balanced_fund / is_special_situation_fund | boolean, nullable | Classification flags. null means unclassified — not false |
management_fee_percentage / gp_commitment_percentage / hurdle_percentage / carry_percentage | number, nullable | Percentages, so 2.00 means 2% — not 0.02. See Field Types and Nulls |
The list response returns only the first nine fields in this table; everything from
term_yearsdown is detail-only.
Real Funds for Testing
| Fund | UUID | Size | Vintage |
|---|---|---|---|
| Wavemaker Pacific 1 | 73541611-0738-46fb-abbd-7e9dcf74b00c | $66M | 2017 |
| Bain Capital Asia III | 50280c30-d626-44db-8aff-7cdf1eb323bb | $3B | 2016 |
Fund Performance
Returns quarterly / annual performance metrics (IRR, DPI, TVPI). Each row is one reporting period.
curl "https://api.altdmp.io/v3/partners/funds/50280c30-d626-44db-8aff-7cdf1eb323bb/performance/" \
-H "Authorization: Bearer YOUR_TOKEN"
performance = requests.get(
f"{BASE}/funds/50280c30-d626-44db-8aff-7cdf1eb323bb/performance/",
headers=headers,
).json()
Example performance row (Bain Capital Asia III, Q4 2024):
{
"uuid": "876b7ca5-f4f3-4262-81bb-a33874b2e199",
"fund_uuid": "50280c30-d626-44db-8aff-7cdf1eb323bb",
"date": "2024-12-31",
"year": 2024,
"quarter": "Q4",
"source": "Limited Partner",
"source_type_key": "fund_per_source_type_lp",
"source_capital_allocator_uuid": "f80754f5-16c7-4aac-9cab-4149285c7220",
"currency": {"iso_code": "USD", "name": "US Dollar"},
"source_url": null,
"irr": 0.1800,
"irr_pct": 18.00,
"dpi": 1.3000,
"rvpi": 0.8000,
"net_multiple": 2.1000,
"profit_usd": 540000000.00,
"drawdowns_usd": 2800000000.00,
"committed_capital_usd": 3000000000.00,
"retained_earnings_usd": null,
"dividends_usd": null,
"net_assets_usd": null,
"carry_unrealised_usd": null,
"carry_realised_usd": null,
"cashflow_usd": null,
"share_redemption_usd": null,
"distributions_usd": null,
"created_at": "2026-06-23T04:25:42.261489Z",
"last_updated_at": "2025-01-15T10:22:00Z"
}
Performance Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Performance record UUID |
fund_uuid | string, nullable | The fund this row belongs to. Returned on the per-fund endpoint as well as the batch endpoint |
date | date string | Reporting-period end date |
year / quarter | integer / string, nullable | Reporting period, e.g. 2024 and "Q4" |
source | string, nullable | Data source display name — one of "Financial Statement", "Fund Manager", or "Limited Partner" |
source_type_key | string, nullable | Machine-readable source type — "fund_per_source_type_fs", "fund_per_source_type_fm", or "fund_per_source_type_lp" |
source_capital_allocator_uuid | string, nullable | The allocator that reported the figures, when the source is an LP |
currency | object, nullable | Reporting currency of the as-reported performance data; the _usd fields are always USD-normalized regardless of this value |
source_url | string, nullable | Link to the source document, when public |
irr | number, nullable | Internal Rate of Return as a fraction — 0.1800 means 18% |
irr_pct | number, nullable | The same figure as a percentage — 18.00 means 18%. Always exactly irr × 100, and null whenever irr is |
dpi | number, nullable | Distributions to Paid-In multiple. A multiple, not a percentage: 1.3000 means 1.3× |
rvpi | number, nullable | Residual Value to Paid-In multiple |
net_multiple | number, nullable | Total Value to Paid-In (TVPI) |
profit_usd / drawdowns_usd / committed_capital_usd / retained_earnings_usd / dividends_usd / net_assets_usd / carry_unrealised_usd / carry_realised_usd / cashflow_usd / share_redemption_usd / distributions_usd | number, nullable | USD-normalized amounts |
created_at / last_updated_at | date-time string | When the record was first created and last changed |
irrdid not change scale — it was a fraction before 2026-08-14 and still is. What changed is that it is now a JSON number rather than a quoted string, andirr_pctwas added beside it. Readirr_pctif you want the percentage; there is no need to multiply by 100 yourself.dpi,rvpi, andnet_multipleare multiples and get no_pctsibling — adpiof1.30is 1.3×, not 130%.
Coverage is sparse beyond the headline metrics. Expect
nullfor most of the cash-flow fields (retained_earnings_usdthroughdistributions_usd) on any given row.
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Supported values: date, irr, irr_pct, dpi, rvpi, net_multiple (prefix with - for descending, default: -date). irr and irr_pct sort identically. An unrecognized value is silently ignored and falls back to -date — this endpoint does not return 400 for a bad ordering |
irr_min / irr_max | Range filter on IRR, as a fraction — irr_min=0.15 means 15%. There is no irr_pct_min; passing irr_min=15 returns an empty page rather than an error |
dpi_min / dpi_max | Range filter on DPI |
rvpi_min / rvpi_max | Range filter on RVPI |
net_multiple_min / net_multiple_max | Range filter on net multiple |
limit | Results per page |
offset | Pagination offset |
Rows where the filtered metric is null are excluded from every range filter above. On this endpoint nulls sort first under a descending ordering and last under an ascending one, unlike the list endpoints where they sort last in both directions.
Batch Performance via POST
Use POST /v3/partners/funds/performance/ (note: no {uuid} in the path) to pull performance records for many funds in one paginated request instead of calling the per-fund .../{uuid}/performance/ endpoint once per fund. The body must contain a non-empty fund_uuid in filter; up to 1,000 UUIDs are accepted per request. Each returned row carries a fund_uuid field so you can join it back to the fund it belongs to.
curl -X POST "https://api.altdmp.io/v3/partners/funds/performance/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "fund_uuid", "value": [
"50280c30-d626-44db-8aff-7cdf1eb323bb",
"3fa85f64-5717-4562-b3fc-2c963f66afa6"
]}
]
}
}'
Rows are ordered by most recent reporting period first and use the same shape as the per-fund performance endpoint, including the fund_uuid join field.
- A missing or empty
fund_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
AUM History
Returns a time series of fund size records.
curl "https://api.altdmp.io/v3/partners/funds/73541611-0738-46fb-abbd-7e9dcf74b00c/aum/" \
-H "Authorization: Bearer YOUR_TOKEN"
aum = requests.get(f"{BASE}/funds/{uuid}/aum/", headers=headers).json()
Example response:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uuid": "a088fa5b-a023-49dc-b1c5-a162bea5a055",
"aum_value_date": "2024-12-31",
"aum_value": 66000000.00,
"aum_value_usd": 66000000.00,
"reporting_currency": {"iso_code": "USD", "name": "US Dollar"}
}
]
}
aum_value is the fund size in reporting_currency; aum_value_usd is the same figure normalized to USD. Both are numbers. The most recent record here is also surfaced as latest_fund_size on the fund detail response.
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -aum_value_date) |
limit | Results per page |
offset | Pagination offset |
LP Commitments
Returns LP commitments into this fund — who invested and how much.
curl "https://api.altdmp.io/v3/partners/funds/50280c30-d626-44db-8aff-7cdf1eb323bb/commitments/" \
-H "Authorization: Bearer YOUR_TOKEN"
commitments = requests.get(
f"{BASE}/funds/50280c30-d626-44db-8aff-7cdf1eb323bb/commitments/",
headers=headers,
).json()
Example commitment row (Bain Capital Asia III LP):
{
"uuid": "449caf29-9825-453c-88ef-ddfffcbb6ca6",
"date": "2016-08-15",
"allocation_type_key": "allocation_type_commitment",
"allocation_type_name": "Commitment",
"allocation_subtype_key": "allocation_subtype_commitment",
"allocation_subtype_name": "Commitment",
"investment_amount_usd": 50000000.00,
"transactions": [
{
"uuid": "af9bbee4-c09e-4d4d-be6a-124b3d4b034f",
"investment_amount_usd": 50000000.00,
"buyer": {
"uuid": "dc8b6720-5e9e-4306-b5fc-4884c8f94e4b",
"name": "GIC Private Limited",
"type_key": "capital_allocator",
"type": "CapitalAllocatorProfile"
}
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Commitment UUID |
date | date string | Commitment date |
allocation_type_key / allocation_type_name | string, nullable | Allocation type |
allocation_subtype_key / allocation_subtype_name | string, nullable | Allocation subtype |
investment_amount_usd | number, nullable | Total committed amount in USD |
transactions | array | Underlying transactions, one per committing LP. May be empty. |
transactions[].uuid | string | Transaction UUID |
transactions[].investment_amount_usd | number, nullable | Committed amount for this transaction in USD |
transactions[].buyer | object, nullable | The committing party (LP): exactly uuid, name, type_key, and type — no registration numbers here, unlike the buyer/seller objects on deals. null when no buyer is recorded |
transactions[].buyer.type_key tells you what kind of entity the LP is — one of capital_allocator, fund, capital_receiver, legal_entity, person, or shareholder_group — and uuid is its ID in that namespace. Join on type_key, not on the type label; see routing by type_key.
This is the fund-side view. The allocator-side feed at
/capital-allocators/{uuid}/commitments/covers the same relationship from the other direction but returns a different shape — a nestedfundobject andcash_value_transacted*amounts instead oftransactions[]andinvestment_amount_usd.
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -date). Supported: date, investment_amount_usd, created_at, updated_at |
limit | Results per page |
offset | Pagination offset |
Portfolio Investments
Returns aggregated investment data for companies this fund has invested in, including investments made through child entities (SPVs, etc.) in the ownership hierarchy.
curl "https://api.altdmp.io/v3/partners/funds/73541611-0738-46fb-abbd-7e9dcf74b00c/investments/" \
-H "Authorization: Bearer YOUR_TOKEN"
investments = requests.get(f"{BASE}/funds/{uuid}/investments/", headers=headers).json()
Example response:
{
"count": 14,
"next": null,
"previous": null,
"results": [
{
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity_uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"capital_receiver_name": "Shopback",
"shares_issued": 1500000.0,
"shares_bought_secondary": 0.0,
"shares_sold": 0.0,
"shares_currently_held": 1500000.0,
"total_invested_usd": 7500000.00,
"first_investment_date": "2019-04-30",
"latest_investment_date": "2022-03-01"
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
capital_receiver_uuid | string | UUID of the capital receiver profile — use with /capital-receivers/{uuid}/ |
legal_entity_uuid | string | UUID of the underlying legal entity |
capital_receiver_name | string | Company name |
shares_issued | number | Shares acquired via primary transactions |
shares_bought_secondary | number | Shares acquired via secondary purchases |
shares_sold | number | Shares sold via secondary transactions |
shares_currently_held | number | Current net shareholding |
total_invested_usd | number | Total cash invested in USD (primary transactions only) |
first_investment_date | date | Date of first investment |
latest_investment_date | date | Date of most recent investment |
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -latest_investment_date) |
limit | Results per page |
offset | Pagination offset |
News
Returns paginated news articles linked to this fund.
curl "https://api.altdmp.io/v3/partners/funds/73541611-0738-46fb-abbd-7e9dcf74b00c/news/" \
-H "Authorization: Bearer YOUR_TOKEN"
news = requests.get(f"{BASE}/funds/{uuid}/news/", headers=headers).json()
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "b3c4d5e6-...",
"date": "2022-06-30",
"headline": "Wavemaker Pacific Closes $60M Fund at Final Close",
"body": "Wavemaker Partners has announced the final close of Wavemaker Pacific 1...",
"source_url": "https://dealstreetasia.com/...",
"type": {"key": "news_type_closing_fund", "name": "Closing of a Fund"}
}
]
}
News Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -date) |
limit | Results per page |
offset | Pagination offset |
Investors
Last updated: 17 August 2026
The Investors endpoint is a unified search across every entity that has been a buyer in a transaction — companies, individuals, and shareholder groups — in a single query. Use it when you want investment totals for an investor and don’t know which kind of entity it is.
This endpoint reports base entity types, not profiles. Every row’s
investor_typeislegal_entity,person, orshareholder_group— it never resolves a firm to its capital allocator or fund profile. Filtering?investor_type=capital_allocatoror?investor_type=fundis accepted but always returns zero results. For allocator- and fund-level views, use Capital Allocators and Funds; for a company’s investors resolved to their profiles, use/capital-receivers/{uuid}/investors/.
Endpoints
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/investors/ | Subscription required |
POST | /v3/partners/investors/ | Subscription required |
List Investors
Each result row represents one investor × allocation type combination. An investor with both equity and debt investments appears as two separate rows.
curl "https://api.altdmp.io/v3/partners/investors/?search=Wavemaker" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
resp = requests.get(
f"{BASE}/investors/",
params={"search": "Wavemaker"},
headers=headers,
)
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"name": "Wavemaker Group",
"investor_type": "legal_entity",
"uuid": "f80754f5-16c7-4aac-9cab-4149285c7220",
"allocation_type_key": "equity",
"allocation_type_name": "Equity",
"total_invested_usd": 87500000.0,
"no_of_invested_companies": 47,
"investments_by_deal_type": {
"seed": {
"amount_invested_usd": 12000000.0,
"no_of_invested_companies": 18
},
"series_a": {
"amount_invested_usd": 35000000.0,
"no_of_invested_companies": 19
},
"series_b": {
"amount_invested_usd": 40500000.0,
"no_of_invested_companies": 10
}
}
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid | string | UUID of the investor entity |
name | string | Investor display name |
investor_type | string | Base entity type — legal_entity, person, or shareholder_group only. This is a key, not a label: it is stable and safe to join and filter on, and there is no separate investor_type_key |
allocation_type_key | string, nullable | Asset class key: equity, debt, allocation_type_commitment, or allocation_type_other |
allocation_type_name | string, nullable | Asset class display name: Equity, Debt, Commitment, Other |
total_invested_usd | number, nullable | Total primary capital deployed (USD) |
no_of_invested_companies | integer | Distinct companies invested in |
investments_by_deal_type | object | Breakdown keyed by deal-stage key, each value {amount_invested_usd, no_of_invested_companies}. Only stages the investor has actually invested in appear — the object is sparse, so read it with .get() rather than assuming a fixed key set |
There are no investment dates on this endpoint. Unlike the per-company
/capital-receivers/{uuid}/investors/rows, an investor row here carries nofirst_investment_dateorlatest_investment_date. Useinvested_on_from/invested_on_toto filter by date, or call the per-company endpoint when you need the actual dates.
The
allocation_type_keyvalues are not uniformly prefixed:equityanddebtare bare, while commitment and other carry anallocation_type_prefix. Match on the exact strings above, or read them from reference data.
Query Parameters
| Parameter | Description |
|---|---|
search | Full-text search on investor name |
investor_type | Filter by base entity type: legal_entity, person, or shareholder_group. capital_allocator and fund are accepted but match nothing |
invested_in_stage | Filter by deal-stage key (e.g. seed, series_a) — the same keys as investments_by_deal_type |
invested_on_from | Investments on or after this date (YYYY-MM-DD) |
invested_on_to | Investments on or before this date (YYYY-MM-DD) |
capital_receiver_headquarters_country_iso_alpha3 | Scope to investors in portfolio companies headquartered in these countries (comma-separated ISO alpha-3, e.g. SGP,MYS) |
capital_receiver_domicile_country_iso_alpha3 | Scope to investors in portfolio companies domiciled in these countries (comma-separated ISO alpha-3) |
ordering | Sort field, prefix with - for descending |
limit | Results per page |
offset | Pagination offset |
Filtering Examples
# All equity investors who made a Seed investment after 2022
curl "https://api.altdmp.io/v3/partners/investors/?invested_in_stage=seed&invested_on_from=2022-01-01" \
-H "Authorization: Bearer YOUR_TOKEN"
# All investor types matching "Temasek"
curl "https://api.altdmp.io/v3/partners/investors/?search=Temasek" \
-H "Authorization: Bearer YOUR_TOKEN"
# Seed investors after 2022
resp = requests.get(
f"{BASE}/investors/",
params={"invested_in_stage": "seed", "invested_on_from": "2022-01-01"},
headers=headers,
)
# Search for Temasek
resp = requests.get(f"{BASE}/investors/", params={"search": "Temasek"}, headers=headers)
Advanced Filter (POST)
Supports the same fields as the GET query parameters, passed as a filters.all array in the request body. The body accepts only the filters object; pass search, ordering, limit, and offset as query parameters — sending them in the body returns 400 Bad Request.
This endpoint’s filter body is narrower than the other list endpoints. It supports a flat
filters.alllist of the field/operator pairs below and rejects anything else with400 Bad Requestand a message naming what it can accept. In particularanyandnotare not available here — combine your conditions inall, or issue separate requests.
filtersmust be a JSON object. A list or scalar —{"filters": ["any"]}— returns400 Bad Requestrather than applying no filter; omitfilters, or sendnullor{}, to get the unfiltered list. Each entry inallmust be an object, and the request body itself must be a JSON object rather than an array.A
?filters=query parameter is ignored here, not rejected. Elsewhere it returns400 Bad Request; on this endpoint the value is dropped and you get the complete unfiltered list with a200. Always send the filter in the request body — and do not treat a200from this endpoint as confirmation that a query-string filter was applied.
Supported field and operator combinations:
| Field | Operators |
|---|---|
investor_type | eq |
name | eq, contains |
search | eq, contains |
invested_in_stage | eq |
invested_on_from | eq, gte |
invested_on_to | eq, lte |
capital_receiver_headquarters_country_iso_alpha3 | eq, in |
capital_receiver_domicile_country_iso_alpha3 | eq, in |
namematches as a substring under botheqandcontains.{"op": "eq", "field": "name", "value": "Wavemaker"}returns every investor whose name contains “Wavemaker”, not just an exact match — pass the full name to narrow to one. A list value is rejected, so filter one name per request.
Investor Filter Fields
| Field | Type | Example |
|---|---|---|
investor_type | string | "legal_entity", "person", or "shareholder_group" — exact match |
name | string | "Temasek" — substring match under eq and contains |
invested_in_stage | string | "seed", "series_a" |
invested_on_from | date string | "2020-01-01" |
invested_on_to | date string | "2024-12-31" |
capital_receiver_headquarters_country_iso_alpha3 | list | ["SGP", "MYS"] |
capital_receiver_domicile_country_iso_alpha3 | list | ["SGP"] |
The two
capital_receiver_*_country_iso_alpha3filters scope the investor list to those who have transacted in portfolio companies headquartered in — or domiciled in — the given countries. In aPOSTbody useop: inwith a list (or a single scalar) value. When both filters are supplied together they AND — an investor must satisfy both constraints.
# Company investors whose name contains "Wavemaker"
curl -X POST https://api.altdmp.io/v3/partners/investors/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "investor_type", "value": "legal_entity"},
{"op": "contains", "field": "name", "value": "Wavemaker"}
]
}
}'
This returns every investor whose name contains “Wavemaker”. To target one, pass its full name; to cover several, issue one request each.
resp = requests.post(
f"{BASE}/investors/",
headers=headers,
json={
"filters": {
"all": [
{"op": "eq", "field": "investor_type", "value": "legal_entity"},
{"op": "contains", "field": "name", "value": "Wavemaker"},
]
}
},
)
What
uuididentifies depends oninvestor_type.
person— a Person UUID. Pass it straight to/people/{uuid}/.legal_entity— a Legal Entity UUID, not a profile UUID. It returns404on/capital-allocators/{uuid}/,/funds/{uuid}/, and/capital-receivers/{uuid}/, and there is no/legal-entities/{uuid}/endpoint in the Partner API. To reach a profile, search that entity bynameor registration number on the relevant profile list endpoint and match onlegal_entity.uuid.shareholder_group— a grouping construct with no detail endpoint.name,uuid, and the investment totals on this row are all the API exposes.
People
Last updated: 17 August 2026
The People resource covers founders, directors, employees, advisors, and other individuals linked to companies or funds.
Endpoints
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/people/ | Subscription required |
POST | /v3/partners/people/ | Subscription required |
GET | /v3/partners/people/{uuid}/ | Subscription required |
GET | /v3/partners/people/{uuid}/roles/ | Subscription required |
POST | /v3/partners/people/roles/ | Subscription required |
GET | /v3/partners/people/{uuid}/investments/ | Subscription required |
GET | /v3/partners/people/{uuid}/news/ | Subscription required |
List People
# All founders at Singapore companies
curl "https://api.altdmp.io/v3/partners/people/?role_type_key=person_association_founder" \
-H "Authorization: Bearer YOUR_TOKEN"
# Directors named "Chan"
curl "https://api.altdmp.io/v3/partners/people/?role_type_key=person_association_director&search=Chan" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
# All founders
founders = requests.get(
f"{BASE}/people/",
params={"role_type_key": "person_association_founder"},
headers=headers,
).json()
# Directors named Chan
directors = requests.get(
f"{BASE}/people/",
params={"role_type_key": "person_association_director", "search": "Chan"},
headers=headers,
).json()
Example response:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"uuid": "f2eac778-a47b-497e-a4c6-ddd71335a404",
"display_name": "Shanru Lai",
"given_name": "Shanru",
"family_name": "Lai",
"location_country_name": "Singapore",
"email": "shanru@shopback.com",
"linkedin_url": "https://linkedin.com/in/shanrulai",
"last_updated_at": "2025-10-16T07:33:30Z"
}
]
}
List Query Parameters
| Parameter | Description |
|---|---|
search | Name search across given and family name. Multiple words are matched independently, so full names like Shanru Lai match regardless of word order. |
role_type_key | Filter by role: person_association_founder, person_association_director, person_association_employee, person_association_advisor |
domicile_country_iso_alpha3 | Filter by the domicile-country ISO alpha-3 code of an associated organization. Repeatable or comma-separated (e.g. SGP,USA). |
headquarters_country_iso_alpha3 | Filter by the headquarters-country ISO alpha-3 code of an associated organization. Repeatable or comma-separated. |
ordering | Sort field |
limit | Results per page |
offset | Pagination offset |
Advanced Filter (POST)
Use POST with a JSON body to filter people by name or location. The body accepts only the filters object; pass search, role_type_key, domicile_country_iso_alpha3, headquarters_country_iso_alpha3, ordering, limit, and offset as query parameters. filters cannot go the other way — a value in ?filters= returns 400 Bad Request on both GET and POST.
Operators, body shapes, and the supported filter field list for this endpoint are on the Filtering page. Note that
eq,ne,in, andninare case-sensitive, and that an unrecognizedopis silently treated aseqrather than rejected.
People Filter Fields
| Field | Type | Example |
|---|---|---|
given_name | string | "Henry" |
family_name | string | "Chan" |
location_country_name | string | "Singapore" |
location_country_iso_alpha3 | string | "SGP" |
date_of_birth | date string | "1985-04-12" |
role_type_keyandrole_type_nameare query parameters, not filter-body fields. Sending either insidefiltersreturns400 Bad Request. Role filtering is combined with the body filters, so pass the role on the query string and the rest in the body — as below.
# Founders based in Singapore — role on the query string, location in the body
curl -X POST "https://api.altdmp.io/v3/partners/people/?role_type_key=person_association_founder" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "eq", "field": "location_country_iso_alpha3", "value": "SGP"}
]
}
}'
resp = requests.post(
f"{BASE}/people/",
headers=headers,
params={"role_type_key": "person_association_founder"},
json={
"filters": {
"all": [
{"op": "eq", "field": "location_country_iso_alpha3", "value": "SGP"},
]
}
},
)
Get Person Detail
# ShopBack co-founder Shanru Lai
curl "https://api.altdmp.io/v3/partners/people/f2eac778-a47b-497e-a4c6-ddd71335a404/" \
-H "Authorization: Bearer YOUR_TOKEN"
uuid = "f2eac778-a47b-497e-a4c6-ddd71335a404"
person = requests.get(f"{BASE}/people/{uuid}/", headers=headers).json()
Example response:
{
"uuid": "f2eac778-a47b-497e-a4c6-ddd71335a404",
"display_name": "Shanru Lai",
"given_name": "Shanru",
"family_name": "Lai",
"location_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"nationality": {"iso_alpha3": "SGP", "name": "Singapore"},
"date_of_birth": null,
"biography": null,
"email": null,
"linkedin_url": "https://www.linkedin.com/in/shanrulai",
"last_updated_at": "2026-07-14T12:22:57.051103Z"
}
| Field | Type | Description |
|---|---|---|
uuid | string | Person UUID |
display_name | string | Full name as displayed |
given_name / family_name | string, nullable | Name parts |
location_country | object, nullable | Where the person is based — {iso_alpha3, name}. Note the list endpoint returns a flat location_country_name string instead of this object |
nationality | object, nullable | {iso_alpha3, name} |
date_of_birth | date string, nullable | Rarely populated |
biography | string, nullable | Free-text biography |
email / linkedin_url | string, nullable | Contact details |
last_updated_at | date-time string | When the record last changed |
The list and detail responses differ on two fields: the list returns
location_country_name(a flat string) and nonationality,date_of_birth, orbiography; the detail returnslocation_countryas an object plus the three extra fields.
Roles
Returns all organisational roles held by a person across their career.
curl "https://api.altdmp.io/v3/partners/people/f2eac778-a47b-497e-a4c6-ddd71335a404/roles/" \
-H "Authorization: Bearer YOUR_TOKEN"
roles = requests.get(f"{BASE}/people/{uuid}/roles/", headers=headers).json()
Example role row:
{
"uuid": "f243d7ca-8386-436c-bb22-2c5c9c19f177",
"person_uuid": "f2eac778-a47b-497e-a4c6-ddd71335a404",
"role_type": {
"key": "person_association_founder",
"name": "Founder"
},
"organization": {
"uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"display_name": "Shopback",
"profile_type_key": "legal_entity",
"profile_type": "legalentity",
"registration_numbers": [
{"reg_number": "201411189G", "authority_type": "UEN"}
]
},
"title": "Co-founder & CEO",
"start_date": "2014-01-01",
"end_date": null,
"is_current": true,
"email": null,
"linkedin_url": null
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Role UUID |
person_uuid | string | The person holding the role. Returned on the per-person endpoint as well as the batch endpoint |
role_type | object, nullable | {key, name} — see Role Type Keys |
organization | object, nullable | The organization: uuid, display_name, profile_type_key, profile_type, plus type-dependent extras. See below |
title | string, nullable | Job title as recorded |
start_date / end_date | date string, nullable | Role dates. Both are commonly null |
is_current | boolean | Derived from end_date being null |
email / linkedin_url | string, nullable | Role-scoped contact details |
The organization object
organization always carries uuid, display_name, profile_type_key, and profile_type, and gains extra keys depending on what the role is attached to. Branch on profile_type_key — it is the same vocabulary used by type_key everywhere else in the API, whereas the profile_type label is spelled differently here than on capital allocator profiles and will change in a future release.
profile_type_key | profile_type | Extra keys |
|---|---|---|
legal_entity | legalentity | registration_numbers — a list of {reg_number, authority_type} |
capital_allocator | capitalallocatorprofile | legal_entity — {uuid, display_name, registration_numbers} for the allocator’s backing company, when it has one |
service_provider | serviceproviderprofile | legal_entity — same shape as above |
capital_receiver | capitalreceiverprofile | none |
fund | fundprofile | none |
null | out_of_scope | none. uuid is null and display_name is the raw company name |
Most roles return legal_entity. Note the last row: out_of_scope means the organization isn’t tracked on the platform, so it is not a kind of entity and gets no key — a null profile_type_key tells you there is nothing to join to.
organization.registration_numbersentries have noauthority_name. They carry onlyreg_numberandauthority_type— narrower than theregistration_numbersreturned everywhere else in the API.
Roles Query Parameters
| Parameter | Description |
|---|---|
role_type_key / role_type_name | Filter to specific role types |
domicile_country_iso_alpha3 | Filter by the domicile-country ISO alpha-3 code of the associated organization. Repeatable or comma-separated. |
headquarters_country_iso_alpha3 | Filter by the headquarters-country ISO alpha-3 code of the associated organization. Repeatable or comma-separated. |
Role Type Keys
These are the only three role types. The name column is the exact value returned in role_type.name.
| Key | Name |
|---|---|
person_association_founder | Founder |
person_association_director | Director |
person_association_employee | Employee |
end_date: null means the person is currently in the role.
Batch Roles via POST
Use POST /v3/partners/people/roles/ to fetch roles for many people in one paginated request instead of calling the per-person GET .../{uuid}/roles/ endpoint once per person. The body must contain a non-empty person_uuid in filter; up to 1,000 UUIDs are accepted per request. Each returned row carries a person_uuid field so you can join it back to the person it belongs to.
curl -X POST "https://api.altdmp.io/v3/partners/people/roles/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"op": "in", "field": "person_uuid", "value": [
"f2eac778-a47b-497e-a4c6-ddd71335a404",
"a1b2c3d4-0000-0000-0000-000000000002"
]}
]
}
}'
The role_type_key, role_type_name, domicile_country_iso_alpha3, and headquarters_country_iso_alpha3 query parameters also apply, letting you narrow a batch to, say, only current directors. Response rows use exactly the same shape as the per-person roles endpoint — person_uuid is present on both.
- A missing or empty
person_uuidinfilter returns400 Bad Request(this endpoint never returns unscoped results). - More than 1,000 UUIDs, or a value that is not a valid UUID, returns
400 Bad Request.
Personal Investments
Returns direct investments made by this person.
curl "https://api.altdmp.io/v3/partners/people/f2eac778-a47b-497e-a4c6-ddd71335a404/investments/" \
-H "Authorization: Bearer YOUR_TOKEN"
investments = requests.get(f"{BASE}/people/{uuid}/investments/", headers=headers).json()
Example response:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"capital_receiver_uuid": "c16a0ffd-4dbb-4f7b-a9ca-a3a47f93be67",
"legal_entity_uuid": "fee788ac-cffe-46f0-9bb5-fedb62992bd8",
"capital_receiver_name": "Shopback",
"shares_issued": 500000.0,
"shares_bought_secondary": 0.0,
"shares_sold": 0.0,
"shares_currently_held": 500000.0,
"total_invested_usd": 250000.00,
"first_investment_date": "2014-01-01",
"latest_investment_date": "2014-01-01"
}
]
}
Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -latest_investment_date) |
limit | Results per page |
offset | Pagination offset |
News
Returns paginated news articles linked to this person.
curl "https://api.altdmp.io/v3/partners/people/f2eac778-a47b-497e-a4c6-ddd71335a404/news/" \
-H "Authorization: Bearer YOUR_TOKEN"
news = requests.get(f"{BASE}/people/{uuid}/news/", headers=headers).json()
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "a1b2c3d4-...",
"date": "2023-03-10",
"headline": "ShopBack Co-founder Shanru Lai Steps Down as CEO",
"body": "Shanru Lai, co-founder of ShopBack, has transitioned out of the CEO role...",
"source_url": "https://techinasia.com/...",
"type": {"key": "news_type_rebranding", "name": "Rebranding"}
}
]
}
News Query Parameters
| Parameter | Description |
|---|---|
ordering | Sort field. Prefix with - for descending (default: -date) |
limit | Results per page |
offset | Pagination offset |
Service Providers
Last updated: 7 August 2026
Service providers are professional-services firms linked to companies — most commonly auditors, but also legal counsel, fund administrators, placement agents, and more.
Endpoints
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/service-providers/ | Subscription required |
POST | /v3/partners/service-providers/ | Subscription required |
GET | /v3/partners/service-providers/{uuid}/ | Subscription required |
List Service Providers
# All auditors
curl "https://api.altdmp.io/v3/partners/service-providers/?service_type=service_provider_type_audit" \
-H "Authorization: Bearer YOUR_TOKEN"
# Find Ernst & Young
curl "https://api.altdmp.io/v3/partners/service-providers/?search=Ernst+%26+Young" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
# All auditors
auditors = requests.get(
f"{BASE}/service-providers/",
params={"service_type": "service_provider_type_audit"},
headers=headers,
).json()
# Find EY
ey = requests.get(
f"{BASE}/service-providers/",
params={"search": "Ernst & Young"},
headers=headers,
).json()
Example response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"uuid": "a3f1b2c4-5d6e-7f80-9102-a3b4c5d6e7f8",
"display_name": "Ernst & Young LLP",
"legal_entity": {
"uuid": "d9e2f3a4-5b6c-7d8e-9f01-a2b3c4d5e6f7",
"display_name": "Ernst & Young LLP",
"year_founded": 1989,
"date_founded": "1989-01-01",
"date_founded_precision": "year",
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{
"reg_number": "T08LL0018E",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
]
},
"service_types": [
{"key": "service_provider_type_audit", "name": "Audit"}
],
"last_updated_at": "2025-10-16T07:33:30Z"
}
]
}
The list
legal_entityhas noheadquarters. It is the compact variant —uuid,display_name,year_founded,date_founded,date_founded_precision,domicile_country,trading_status,registration_numbers. Fetch the detail response for headquarters, contact details, and people.
Service provider records are often thinly populated: expect
nullforyear_founded,date_founded,domicile_country, andtrading_status, and[]forregistration_numbers.
Query Parameters
| Parameter | Description |
|---|---|
search | Full-text search on firm name |
service_type | Filter by service type key (see table below) |
ordering | Sort field |
limit | Results per page |
offset | Pagination offset |
POSTto this path for an advanced filter body. Supported filter fields aredisplay_name,description,legal_entity_uuid,service_type_key, andservice_type_name— this is the only list endpoint that lets you look a record up by the legal entity behind it. See the Filtering page for the grammar and operators.
Service Type Keys
The name column is the exact value returned in service_types[].name.
| Key | Name |
|---|---|
service_provider_type_audit | Audit |
service_provider_type_tax | Tax |
service_provider_type_compliance | Compliance |
service_provider_type_law_firm | Law Firm |
service_provider_type_investment_bank | Investment Bank |
service_provider_type_merchant_bank | Merchant Bank |
service_provider_type_commercial_bank | Commercial Bank |
service_provider_type_placement_agent | Placement Agent |
service_provider_type_fund_administrator | Fund Administrator |
service_provider_type_lender | Lender |
service_provider_type_valuation_firm | Valuation Firm |
service_provider_type_management_consultant | Management Consultant |
service_provider_type_financing_advisory | Financing Advisory |
service_provider_type_lp_consultant | LP Consultant |
service_provider_type_business_intermediary | Business Intermediary |
service_provider_type_bus_dev_company | Business Development Company |
service_provider_type_crowdfunding_platform | Crowdfunding Platform |
service_provider_type_insurance_provider | Insurance Provider |
service_provider_type_recruiting_firm | Recruiting Firm |
service_provider_type_software_provider | Software Provider |
Fetch the authoritative list at runtime with
GET /reference-data/?type=enums&enum_categories=service_typesrather than hard-coding it.
Get Service Provider Detail
curl "https://api.altdmp.io/v3/partners/service-providers/{uuid}/" \
-H "Authorization: Bearer YOUR_TOKEN"
uuid = "..."
provider = requests.get(f"{BASE}/service-providers/{uuid}/", headers=headers).json()
Example response (Ernst & Young LLP):
{
"uuid": "a3f1b2c4-5d6e-7f80-9102-a3b4c5d6e7f8",
"display_name": "Ernst & Young LLP",
"legal_entity": {
"uuid": "d9e2f3a4-5b6c-7d8e-9f01-a2b3c4d5e6f7",
"display_name": "Ernst & Young LLP",
"description": "Ernst & Young LLP is a professional services firm providing audit, tax, and advisory services.",
"year_founded": 1989,
"date_founded": "1989-01-01",
"date_founded_precision": "year",
"is_female_founder": null,
"domicile_country": {"iso_alpha3": "SGP", "name": "Singapore"},
"headquarters": {
"country_name": "Singapore",
"country_iso_alpha3": "SGP",
"state_name": null,
"city_name": "Singapore"
},
"trading_status": {"key": "operating", "name": "Operating"},
"registration_numbers": [
{
"reg_number": "T08LL0018E",
"authority_type": "UEN",
"authority_name": "Accounting and Corporate Regulatory Authority"
}
],
"alternate_names": [
{"name": "EY Singapore", "type": "Other", "type_key": "alt_name_other"}
],
"website_url": "https://www.ey.com/en_sg",
"email": null,
"phone": null,
"founders": [],
"directors": [],
"auditors": []
},
"service_types": [
{"key": "service_provider_type_audit", "name": "Audit"}
],
"last_updated_at": "2025-10-16T07:33:30Z",
"description": null,
"public_notes": null
}
| Field | Type | Description |
|---|---|---|
uuid | string | Service provider profile UUID |
display_name | string | Firm name |
legal_entity | object, nullable | The underlying registered company, in the full variant — adds description, headquarters, alternate_names, website_url, email, phone, founders, directors, and auditors over the list variant |
service_types | array | {key, name} per service offered — see Service Type Keys |
last_updated_at | date-time string | When the record last changed |
description | string, nullable | Profile-level description. Distinct from legal_entity.description, and usually null |
public_notes | string, nullable | Free-text notes |
Reference Data
Last updated: 7 August 2026
The reference data endpoint exposes the full set of taxonomies and lookup lists used across the Partner API. Use it to build filter dropdowns, validate field values, and understand what keys are valid.
Cache this response. Reference data changes infrequently. Fetch it once at startup and cache it locally rather than calling it on every user interaction.
Endpoint
| Method | Endpoint | Access |
|---|---|---|
GET | /v3/partners/reference-data/ | Subscription required |
Fetch All Reference Data
curl "https://api.altdmp.io/v3/partners/reference-data/" \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
BASE = "https://api.altdmp.io/v3/partners"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
ref = requests.get(f"{BASE}/reference-data/", headers=headers).json()
Fetch Specific Sections
Use the type parameter to request only the data you need:
# Only enums and countries
curl "https://api.altdmp.io/v3/partners/reference-data/?type=enums,countries" \
-H "Authorization: Bearer YOUR_TOKEN"
# Only specific enum categories
curl "https://api.altdmp.io/v3/partners/reference-data/?type=enums&enum_categories=allocation_types,themes" \
-H "Authorization: Bearer YOUR_TOKEN"
# Fetch only enums
enums = requests.get(
f"{BASE}/reference-data/",
params={"type": "enums"},
headers=headers,
).json()
# Fetch specific categories
resp = requests.get(
f"{BASE}/reference-data/",
params={"type": "enums", "enum_categories": "allocation_types,themes"},
headers=headers,
).json()
type Parameter Values
| Value | Returns |
|---|---|
enums | All enumerated choice values grouped by category |
countries | All countries with iso_alpha3 and name |
cities | Cities with name, state_name, and country_iso_alpha3 |
industries | Industry codes with code and description |
business_sic_codes | Business SIC codes with code, description, and country_iso_alpha3 |
Omit type to fetch all sections at once.
Enum Categories
When type=enums is requested, use enum_categories to narrow to specific groups:
The Count column is the number of values in each category, so you can tell an abridged sample below from a complete list.
| Category Key | Count | Values (samples for the large categories) |
|---|---|---|
allocation_types | 4 | Commitment, Debt, Equity, Other |
allocation_subtypes | 9 | Commitment, Debt Transactions, Other, Venture Capital (VC), Private Equity (PE), Mergers & Acquisitions (M&A), Distressed Transactions, Liquidity Events, Other Equity |
allocation_deal_types | 75 | Pre-Seed, Seed, Series A – Series K+, Buyout / LBO, Growth / Expansion, IPO, Secondary Transaction, Convertible Debt, Term Loan, Bridge Loan, Commitment, Establishment, ESOP, … |
capital_allocator_types | 25 | Venture Capital Firm, Private Equity Firm, Family Office - Single, Family Office - Multi, Family Office - Unknown, Sovereign Wealth Fund, Pension Fund (Manager) - Corporate / Other / Public / Union, Endowment Fund Manager, Fund of Funds Manager, Fund Manager, Corporate Investor, Banking Institution, Insurance Company, Investment Firm, Development Finance Institution (DFI), Wealth / Asset Manager, … |
capital_allocator_allocates_from | 3 | Balance Sheet, Fund, Unknown |
person_role_types | 3 | Director, Employee, Founder |
service_types | 20 | Audit, Tax, Compliance, Law Firm, Investment Bank, Merchant Bank, Commercial Bank, Placement Agent, Fund Administrator, Lender, Valuation Firm, Management Consultant, Financing Advisory, LP Consultant, Business Intermediary, Business Development Company, Crowdfunding Platform, Insurance Provider, Recruiting Firm, Software Provider |
preferred_fund_types | 0 | Returns an empty array. The preferred_fund_types values on capital allocator and fund profiles are drawn from allocation_deal_types (e.g. venture_general_other / “Venture - General / Other”) — validate them against that category instead |
fund_statuses | 14 | Announced, Closed, Raising, Evergreen, First Close, Second Close, Third Close, Fourth Close, Open, Open - With first close, Upcoming, Estimated, Liquidated, Unknown |
trading_statuses | 3 | Operating, Inactive, Closed |
deal_provenances | 3 | Filed with Regulator, Filed via FOIA, Reported |
fund_performance_sources | 3 | Financial Statement, Fund Manager, Limited Partner |
business_models | 3 | B2B (Business-to-Business), B2C (Business-to-Consumer), P2P (Peer-to-Peer) |
techs | 61 | AgriTech, AI / GenAI / MLTech, BioTech, CleanTech, DeepTech, EduTech, EnergyTech, FinTech, GovTech, HealthTech, HRTech, InsurTech, LegalTech, MarTech, PropTech, RetailTech, TransportTech, … |
themes | 40 | AI / GenAI / ML, Business Applications / SaaS, Buy Now Pay Later (BNPL), Climate / Green / Clean, Cybersecurity, Data Management & Analytics, Digital / Neo Banking, Digital Health Solutions, Payments, Quantum Computing, Smart City, Web 3 / Blockchain / Distributed Ledger, Wellness, … |
horizontals | 12 | AI / GenAI / ML, AR / VR / XR / Spatial Computing, Collaboration & Productivity Suites, Connectivity & Communications, Core Compute / Edge Computing / Cloud Compute, Customer Stack, Data Foundations & Engineering Platforms, Data Management & Analytics, Digital Identity & Access Management, IoT (Internet of Things), Marketplaces, Web 3 / Blockchain / Distributed Ledger |
News-article types are not in this endpoint. The
typeobject on news rows usesnews_type_*keys (e.g.news_type_funding,news_type_acquisition) that noenum_categoriesvalue exposes. Readtype.namefrom the news rows themselves.
Example Response Structure
A full response (no type parameter) has five top-level keys. Arrays are truncated here — in reality each holds every value on the platform.
{
"enums": {
"allocation_types": [
{"key": "equity", "name": "Equity"},
{"key": "debt", "name": "Debt"},
{"key": "allocation_type_commitment", "name": "Commitment"},
{"key": "allocation_type_other", "name": "Other"}
],
"allocation_subtypes": [
{"key": "venture_capital", "name": "Venture Capital (VC)"},
{"key": "private_equity", "name": "Private Equity (PE)"}
],
"allocation_deal_types": [
{"key": "preseed", "name": "Pre-Seed"},
{"key": "seed", "name": "Seed"},
{"key": "series_a", "name": "Series A"}
],
"themes": [
{"key": "themes_ai_genai_ml", "name": "AI / GenAI / ML"},
{"key": "themes_payments", "name": "Payments"}
],
"horizontals": [{"key": "horizontals_marketplaces", "name": "Marketplaces"}],
"business_models": [
{"key": "business_models_b2b", "name": "B2B (Business-to-Business)"}
],
"techs": [{"key": "techs_fintech", "name": "FinTech"}],
"capital_allocator_types": [
{"key": "ca_type_venture_capital_firm", "name": "Venture Capital Firm"}
],
"capital_allocator_allocates_from": [
{"key": "allocates_from_fund", "name": "Fund"}
],
"person_role_types": [
{"key": "person_association_founder", "name": "Founder"}
],
"service_types": [{"key": "service_provider_type_audit", "name": "Audit"}],
"preferred_fund_types": [],
"trading_statuses": [{"key": "operating", "name": "Operating"}],
"fund_statuses": [{"key": "fund_status_closed", "name": "Closed"}],
"deal_provenances": [
{"key": "deal_txn_provenance_filed_regulator", "name": "Filed with Regulator"}
],
"fund_performance_sources": [
{"key": "fund_per_source_type_lp", "name": "Limited Partner"}
]
},
"countries": [
{"iso_alpha3": "SGP", "name": "Singapore"},
{"iso_alpha3": "IDN", "name": "Indonesia"}
],
"cities": [
{"name": "Singapore", "state_name": null, "country_iso_alpha3": "SGP"}
],
"industries": [
{"code": "0602", "description": "Retail Trade (Except Vehicles)"}
],
"business_sic_codes": [
{"code": "47910", "description": "Retail sale via internet", "country_iso_alpha3": "SGP"}
]
}
Enum keys are not consistently prefixed. Some categories prefix every key (
themes_*,fund_status_*,service_provider_type_*), others don’t (equity,debt,seed,operating), and a few are mixed —allocation_typesreturns bareequityanddebtalongside prefixedallocation_type_commitmentandallocation_type_other. Never construct a key from a display name; always read it from this endpoint.
enumsvalues are{key, name}pairs,countriesare{iso_alpha3, name},citiesare{name, state_name, country_iso_alpha3}, and bothindustriesandbusiness_sic_codesare{code, description}(withbusiness_sic_codesaddingcountry_iso_alpha3). When atypeparameter is supplied, only the requested top-level keys appear.
Usage Pattern
# Load reference data once at startup and cache
ref = requests.get(f"{BASE}/reference-data/?type=enums,countries", headers=headers).json()
# Build a lookup: key -> display name for deal types
deal_type_map = {
item["key"]: item["name"]
for item in ref["enums"]["allocation_deal_types"]
}
# Use it to label API results
for deal in deals["results"]:
label = deal_type_map.get(deal["allocation_deal_type_key"], deal["allocation_deal_type_key"])
print(f"{deal['date']}: {label}")
Changelog
Last updated: 25 August 2026
Most recent changes first.
2026-08-25
?search= no longer matches description text
?search= now means the same thing on every Partner API list endpoint: it matches what an entity is called, not the prose written about it. description is no longer searched on any of them.
| Endpoint | What ?search= matches |
|---|---|
GET /v3/partners/capital-receivers/ | Company name, alternate names, registration number |
GET /v3/partners/capital-allocators/ | The allocator’s own display_name, and the linked legal entity’s display_name |
GET /v3/partners/funds/ | The fund’s display_name, and its fund manager’s name |
GET /v3/partners/service-providers/ | The firm’s display_name |
Nothing else about ?search= changed — same parameter, same response shape, same pagination.
Expect fewer rows on all four. A term that appeared mostly in description text loses most of its matches: ?search=tech on capital receivers returned 39,438 rows and now returns 14,229. The request still succeeds, and nothing in the response marks the narrowing, so a saved search whose row count you track will simply drop. Re-check any term you match on that is a topic or a descriptor rather than a name.
To keep matching description text, filter on it explicitly instead. description is a supported filter field on all four endpoints, and contains is case-insensitive:
{"filters": {"description": {"op": "contains", "value": "tech"}}}
Send it as a POST to the same list endpoint. See Filtering.
Two documentation fixes went with this. The capital receivers and capital allocators pages both claimed description coverage and no longer do. The funds page described ?search= as covering the fund’s name alone — it has always also matched the fund manager’s name, and now says so. The service providers page was already accurate.
2026-08-20
Financial-statement file URLs — lifetime and expiry behavior documented
The financial_statements_audited[] and financial_statements_extracted[] arrays on capital receiver detail are the only place the Partner API returns files. Their url values were documented as signed and expiring, without saying for how long or what an expired link does. The lifetime is now stated: one hour from the response, with the Expires parameter in the URL carrying the exact deadline as a Unix timestamp. No API behavior changed — this was already true.
Also newly documented:
- Each request mints a fresh signature, so a URL stored in a database, a queue, or a cached response is dead within the hour. Re-request the detail endpoint rather than persisting the link.
- An expired link is not a JSON error. The asset host returns
403 Forbiddenwith an XML body (<Error><Code>AccessDenied</Code></Error>), not the JSON error shape the rest of the API uses. Integrations that parse every failure as JSON will break on it. - The signature alone authorizes the download — no
Authorizationheader is involved — so a live URL is effectively a credential for that document.
Migration guide listed the financial-statement arrays under the wrong entity
Migrating from v2 to v3 listed financial_statements_audited[] and financial_statements_extracted[] in the Capital Providers → Capital Allocators field mapping. Both are returned by capital receiver detail only; GET /v3/partners/capital-allocators/{uuid}/ has never returned them. The rows have moved to the Companies → Capital Receivers mapping, where they belong. If you read that table while porting an allocator integration, the fields were never available on that endpoint.
2026-08-19
New Filtering page — operators, body shapes, and the complete field lists
Filter documentation was spread across the introduction, the migration guide, and repeated on each endpoint page, and several parts of the grammar were written down nowhere. Filtering is now the single reference: every operator with its exact matching behavior, both accepted body shapes, the supported filter field list for each endpoint, and the batch-endpoint rules. The endpoint pages keep their own field tables and link here for the grammar. No API behavior changed — all of this was already true.
Behavior that was previously undocumented, worth checking your integration against:
eq,ne,in, andninare case-sensitive;contains,ncontains,startswith, andendswithare not. Aneqon"sgp"returns zero rows where"SGP"returns the Singapore-domiciled set. The failure is an empty result set, not an error, so a filter with the wrong casing looks like a filter that matched nothing. Prefer*_keyfields for exact matching — keys have no casing to get wrong. This inconsistency is a known bug; see Case sensitivity for what changes when it is fixed.- An unrecognized
opis silently treated aseqrather than returning400, so a typo in the operator name reads as a working filter. - Seven field names are accepted and then not applied, returning
200with a wider result set than the filter implies:funding_statusandhas_vc_transactionson capital receivers;nationality_name,nationality_iso_alpha3,is_employee, andassociated_ca_typeson people;transaction_labelon deals. See Fields Accepted but Not Applied. - On five of the batch endpoints, conditions beyond the required UUID
infilter have no effect. The request returns200and every row for the UUIDs you passed, with nothing marking the dropped condition. Filter those results client-side, or call the per-entity endpoint where the fields are honored. - A batch endpoint’s required
inleaf must sit directly inside a root-levelall. The other body shapes this documentation describes are not recognized there, and return400reporting the filter as missing even though the UUIDs are in the body. search,ordering,limit, andoffsetin a request body never take effect. Most endpoints return400; the batch endpoints other thanPOST /people/roles/, andPOST /capital-receivers/{uuid}/deals/, discard them without one.
Newly documented, nothing changed:
- The field-keyed body form —
{"filters": {"latest_valuation_usd": {"op": "gte", "value": 50000000}}}— along with its list shorthand (anin) and scalar shorthand (aneq), and the fact that field keys and a logical block can sit side by side at the root. This form has always worked, but appeared in these docs only inside malformed-input examples. - The supported filter field list for every endpoint — the contractual surface, and the only names covered by our compatibility guarantees — replacing the previous per-page selections of common fields.
POST /v3/partners/service-providers/had no filter documentation at all. Its fields aredisplay_name,description,legal_entity_uuid,service_type_key, andservice_type_name— the only list endpoint that filters onlegal_entity_uuid.
Data model — profiles per entity, and why counterparty UUIDs move
Data Model described bi-residency only across roles. It now covers how many profiles one root record can carry, and the two ways a counterparty uuid changes underneath you. No API behavior changed.
Field-location corrections worth checking your integration against:
legal_entity_uuidis returned on investment rows only — the/investments/sub-resource on capital allocators, funds, and people. It was previously documented as also present on investor and cap-table rows. It is not:/capital-receivers/{uuid}/investors/rows and both managed and snapshot cap-table rows carry a profile-resolveduuidand no root UUID at all. If you have been readinglegal_entity_uuidoff those rows, it has always been absent.capital_receiver_uuidis returned on investment rows and on every batch response row (deals, financials, news, deal share types) — not on cap-table rows, where it was also previously documented.preferred_allocation_typedescribes one profile, not the firm. It was documented as “the primary asset class the firm allocates to”, which reads as one allocator profile per firm.
New guidance:
- How Many Profiles Per Root Record — a capital receiver and a fund are one per legal entity; a capital allocator is one per preferred allocation type, so a firm running equity and debt strategies returns two rows from
/capital-allocators/with twouuidvalues and one sharedlegal_entity.uuid; service providers are not limited at all. Any figure you total per firm has to collapse on the root UUID first, or a multi-strategy firm is counted once per profile. - Counterparty UUIDs Are Not Stable Identifiers — the
uuidon abuyer,seller,shareholder,organization, or investor row is resolved per row, at fetch time, to the most specific profile that entity currently has. Two consequences: the same company resolves to its capital allocator profile where it is the investor and to its capital receiver profile where it is the investee; and once a company gains a profile it did not have before, the same historical row starts returning the new profile’s UUID, with nothing in the response indicating the identifier moved. This extends the 2026-08-07 note that these UUIDs are not always legal-entity IDs. Key your own party or company table on the root UUID —legal_entity.uuid, or the person UUID — and treat the counterpartyuuidas a per-row pointer. - The same section lists where to get a root UUID for each response shape, and notes that pooled holders (ESOP, “Other Shareholders”,
shareholder_group) have no root record to resolve.
2026-08-17
A filters query parameter now returns 400 instead of being silently ignored
filters has always been a request-body parameter. A value passed as ?filters=… was discarded before it was parsed, so the request succeeded with 200 OK and returned the complete unfiltered result set, with nothing in the response indicating the filter had been dropped. A caller filtering for one country got every country and no error.
It now returns 400 Bad Request:
{
"filters": "`filters` must be sent in the JSON request body on this endpoint, not as a query-string parameter.",
"status_code": 400
}
Note the shape: the message is keyed by filters, not under detail. See Error Responses → 400 response bodies.
Where it applies. The capital receivers, capital allocators, funds, people, and service providers lists, on GET as well as POST. The batch POST endpoints are unchanged in effect: they read their required UUID in filter from the body, so a query-string filters leaves the body empty and already returned 400. /v3/partners/investors/ is the one endpoint that still ignores a query-string filters rather than rejecting it — it validates its filter body separately. Do not rely on that.
What to check. If a request of yours has been returning more rows than your filter should allow, this is the likely cause, and you will now see the 400 instead. Move the filter into the request body and use POST. A bare ?filters= with no value is unaffected — it expresses no filter, and is still accepted.
Same principle as the strict filter-body rules in the 2026-08-07 entry: a filter you believe restricts rows must never silently widen them.
filters removed from the OpenAPI schema as a query parameter
The published schema advertised filters as a query parameter on 38 Partner API operations, none of which honored it. Several were GET-only sub-resources — /capital-allocators/{uuid}/funds/, /{uuid}/news/, /{uuid}/aum/ — which accept no request body at all, so the parameter documented filtering there was no way to perform. It has been removed everywhere.
If you generate a client from the schema, the filters query argument will disappear from these operations on your next regeneration. Nothing that worked before stops working: the parameter never had an effect. Pass the filter in the POST body instead, as the request examples in the schema already show.
Long URLs no longer fail opaquely
The request-line limit is now 8190 bytes across all environments; it was previously lower, and differed between them. A URL over the limit is still rejected before the API runs — returning 400 as HTML rather than JSON — but the ceiling is now consistent and roughly double what it was. See Error Responses → Very long URLs.
2026-08-14
⚠️ Breaking: all numeric values are now JSON numbers
This is a breaking change to every endpoint. Amounts, percentages, multiples, and rates that were previously returned as quoted strings are now returned as JSON numbers. There is no dual-serving period and no opt-in header — the change lands in one release. If your integration reads any of these fields as text, update it before this release reaches you.
| Field | Before | After |
|---|---|---|
aum_value_usd | "200000000.00" | 200000000.00 |
irr | "0.1800" | 0.1800 |
percentage_held_absolute | "18.50" | 18.50 |
What breaks. Anything that treats these values as strings: a JSON-schema or generated client that types them as string, string comparison (v === "0.00"), string methods on the value (v.replace, v.trim, v.startsWith), or a strongly-typed deserializer that will now reject a number where it expected text. Code that already coerced (float(v), Number(v), Decimal(str(v))) keeps working unchanged.
No value changed. Only the JSON type did. Every figure is the same figure, at the same precision.
Every affected field, across all endpoints:
| Endpoint | Fields |
|---|---|
| Fund detail | management_fee_percentage, gp_commitment_percentage, hurdle_percentage, carry_percentage, latest_fund_size.aum_value, latest_fund_size.aum_value_usd |
| Fund performance | irr, dpi, rvpi, net_multiple, and all eleven _usd cash-flow amounts |
| Fund / capital allocator AUM | aum_value, aum_value_usd |
| Fund LP commitments | investment_amount_usd, transactions[].investment_amount_usd |
| Capital allocator detail | latest_aum.aum_value, latest_aum.aum_value_usd |
| Capital allocator LP commitments | cash_value_transacted, cash_value_transacted_usd |
| Capital receiver detail | The whole funding object (total_funding_usd, latest_valuation_usd, latest_investment_amount, and the six equity/debt breakdowns), plus financials[] operating_revenue_usd, earnings_before_tax_usd, liabilities_usd, operating_revenue_growth_yoy_pct |
| Financials (capital receiver and capital allocator) | Every monetary line item and every annual_*_yoy_growth_pct |
| Cap tables (managed) | percentage_held_absolute, percentage_held_aggregate, holding_value_usd, and the same keys inside aggregations |
| Cap tables (snapshot) | percentage_held |
| Deals | transactions[].price_per_share_usd |
Decimal places are not contractual. A value carries the precision it is stored at, which varies by field — 18.50, 0.1800, 40.0000, and 374.0000000000 are all things you will see. Read the value, not the digits; JSON.parse discards trailing zeros anyway. If you need exact decimal arithmetic, parse into a decimal type rather than a float (Python: json.loads(body, parse_float=decimal.Decimal)).
Only responses are affected. Nothing about request syntax changed: POST filter bodies, query-parameter filters, and ordering all behave exactly as before.
See Introduction → Field Types and Nulls.
New irr_pct on fund performance
GET /v3/partners/funds/{uuid}/performance/ and the batch POST /v3/partners/funds/performance/ now return irr_pct alongside irr. irr is a fraction (0.1800); irr_pct is that value × 100 (18.00). It is null whenever irr is.
irr itself did not change scale — it was a fraction before and still is. irr_pct exists so the scale is stated in the field name rather than inferred, and so you do not have to multiply.
ordering now accepts irr_pct as well as irr; the two sort identically. Note that this endpoint silently falls back to -date for an unrecognized ordering value rather than returning 400 — so a sort that appears to do nothing is worth checking against the supported list.
dpi, rvpi, and net_multiple are multiples, not percentages, and get no _pct sibling. A dpi of 1.30 means 1.3×.
Fund performance range filters were always available
irr_min / irr_max, dpi_min / dpi_max, rvpi_min / rvpi_max, and net_multiple_min / net_multiple_max work on /funds/{uuid}/performance/ and are now documented. The Migration Guide previously listed them as unavailable in v3, which was wrong.
irr_min and irr_max filter on the fraction, matching the irr response field — irr_min=0.15 means 15%. There is no irr_pct_min, and irr_min=15 returns an empty page rather than an error. No API behavior changed here; only the documentation.
2026-08-07
New type_key and profile_type_key — the fields to join on
Every object that references an entity without knowing its kind in advance now returns a stable snake_case key alongside the existing display value. Nothing was removed; these are additions.
| Object | New field | Alongside |
|---|---|---|
Deal transactions[].buyer / .seller | type_key | type |
Cap-table results[].shareholder (managed and snapshot) | type_key | type |
Fund LP commitment transactions[].buyer | type_key | type |
| Capital allocator profile (list and detail) | profile_type_key | profile_type |
Person role organization | profile_type_key | profile_type |
Both draw from one vocabulary: capital_allocator, capital_receiver, fund, legal_entity, person, shareholder_group, service_provider, plus other and alt on cap tables, and null where the row references no entity at all.
Join, look up, filter, and group on the _key fields. The display halves — type and profile_type — spell the same concept two different ways today ("CapitalAllocatorProfile" versus "capitalallocatorprofile"), and a future release will change what they present to readable labels like "Capital Allocator". Neither field is being removed, but anything keyed on the display string will re-partition when that lands. Code keyed on type_key / profile_type_key is unaffected.
The same rule already applied to the older pairs (allocation_type_key / allocation_type_name, key / name inside nested choice objects) and is now written down in Introduction → Keys and Display Values, with per-namespace routing in Data Model → Telling Which Namespace a UUID Belongs To.
Every response example now shows the complete shape
Response examples across all endpoint pages were abridged, and several had fields at the wrong nesting level or with the wrong type. Each one has been regenerated against the live v3 API so it shows every field the endpoint returns. No API behavior changed — this is a documentation correction throughout.
Field-level corrections worth checking your integration against:
- Deals (
/capital-receivers/{uuid}/deals/and the batch endpoint) gained the newly added deal-leveluuid, pluscapital_receiver_uuid,share_class,price_per_share_usd,description, andheadline. Transaction rows gaineduuid,date,nature_of_transaction,transaction_type, the fourallocation_type*/allocation_subtype*fields, and the buyer/seller registration identifiers. See Capital Receivers → Deals. - Capital receiver list and detail:
display_name,year_founded,date_founded, anddate_founded_precisionare nested underlegal_entity, not top-level as previously shown. The list also returnsthemes,horizontals,techs,business_models, andindustries; the detail also returnsfinancials[],financial_statements_audited[], andfinancial_statements_extracted[], which were undocumented. - Cap tables:
aggregationsuses*_aggregatekeys (shares_issued_aggregate,percentage_held_aggregate,holding_value_usd, …) — the previously documentedtotal_shares_issued/total_shares_heldnever existed. Rows also carrychild_entities,child_entities_count,holding_value_usd,is_held_in_treasury, and theshares_bought_secondary_*pair. - Registration numbers are
{reg_number, authority_type, authority_name}. Examples that showedauthority_labelwere wrong. - Buyer, seller, and shareholder
uuidvalues are not always legal-entity IDs. They point at the most specific record the entity has, and the newtype_keysays which. This was previously implied only by thetypelabel. - Capital allocator LP commitments (
/capital-allocators/{uuid}/commitments/) return a nestedfundobject withallocation_type,allocation_subtype,provenance, andcash_value_transacted/cash_value_transacted_usd— not thebuyer/seller/investment_amount_usdshape previously shown. - Fund detail:
structureis a plain string (e.g."Limited Partnership"), not a{key, name}object. Fee percentages andlatest_fund_sizeamounts were decimal strings at this date — superseded on 2026-08-14. - Fund performance gained eleven previously undocumented cash-flow fields, plus
source_capital_allocator_uuid,source_url, andcreated_at.irr,dpi,rvpi, andnet_multiplewere decimal strings at this date — superseded on 2026-08-14. - Investors list (
/investors/) does not returnfirst_investment_dateorlatest_investment_date; those exist only on the per-company/capital-receivers/{uuid}/investors/rows. - AUM records (capital allocator and fund) include
uuidand the reporting-currencyaum_valuealongsideaum_value_usd. - People: the person detail response includes
display_name,location_country,nationality,date_of_birth,biography, andlast_updated_at. Role rows includeperson_uuidandorganization.registration_numbers.
Filter-syntax corrections:
filtersmust start with a logical operator. A bare condition —{"filters": {"op": "eq", …}}— returns400 Bad Request. Wrap even a single condition inall. Examples using the bare form have been corrected.allandanytake an array;nottakes a single condition object, or an array negated as a whole.- Malformed filter bodies now return
400 Bad Requestwith a message describing the problem, instead of a500. This covers a non-object entry insideall/any/not, the same mistake in the flat field-keyed form ({"name": {"all": ["oops"]}}), arangewithout exactly two values, and a request body that is a JSON array or scalar rather than an object. filtersmust be an object. A list or scalar —{"filters": ["any"]}— previously returned the complete unfiltered result set with a200, because both the validator and the parser independently gave up on a non-object and the body passed every check while applying no filter. It now returns400. Omittingfilters, or sendingnullor{}, still means “no filter” and is unaffected.- An empty
notnow returns400 Bad Request.{"not": []},{"not": {}}, and{"not": {"all": []}}compiled to noWHEREclause at all, so a body asking to exclude rows returned every row with a200. An emptyalloranyis unchanged and remains a permissive no-op — that is a caller who supplied no conditions, not one whose exclusion was silently dropped. /investors/validates its filter body. That endpoint accepts a flatfilters.alllist of a fixed set of field/operator pairs, now documented in Investors → Advanced Filter (POST).any,not, and unsupported operators previously either returned the complete unfiltered result set with a200or failed with a500; both now return400naming what is accepted. It also ignoredopentirely, sonereturned the same rows aseq.- Deal filters match display names. The deals
POSTfilter acceptsallocation_typewith"Equity"; there is noallocation_type_keyfilter field. - Enum keys in examples are now real values. Notably
fund_status_activedoes not exist (usefund_status_raising), the audit-opinion key isaudit_opinion_unqualifiedwith name"Unqualified Opinion", and newstypekeys arenews_type_*.
New guidance:
- Introduction → Field Types and Nulls explains which numeric fields come back as JSON strings and which as numbers, and what
nullmeans for booleans and amounts. (The string/number split it described was removed on 2026-08-14 — everything is a number now.) - Reference Data → Enum Categories now lists the true value count per category and flags that
preferred_fund_typesreturns an empty array.
2026-08-04
Error responses now fully documented
Authentication → Error Responses now describes what an error body actually contains, instead of just listing statuses. No API behavior changed — these responses were always returned, they were simply not written down.
- Error bodies carry
status_code(repeating the HTTP status) anddetail. Both are shown, with the exactdetailtext for401,403,404, and500, which is fixed per status. 404and500are documented for the first time, including the two distinct404messages — a mistyped URL reads differently from a missing record, so the two are distinguishable.400bodies come in two shapes: a list of validation messages withstatus_code, or a single string without it. Both are documented, along with the recommendation to accept either and to take the status from the HTTP response rather than the body.- Which statuses apply where: every endpoint can return
401,403, and500; endpoints taking a UUID in the path can also return404; endpoints accepting a body or filter parameters can also return400.
2026-07-20
Validated ordering on the funds and capital-allocators lists
The ordering query parameter on the funds list (GET/POST /v3/partners/funds/) and the capital-allocators list (GET/POST /v3/partners/capital-allocators/) is now validated against a fixed set of fields per endpoint, matching the behavior already in place for capital receivers. An unsupported or aliased field now returns 400 Bad Request listing the valid fields, rather than a server error.
- Funds accept
display_name,vintage_year,term_years,created_at, andupdated_at. See Funds → List Funds. - Capital allocators accept
display_name,cheque_size_min,cheque_size_max,cheque_size_avg,target_allocation,median_valuation,current_allocation,dry_powder,stated_count_of_investments,created_at, andupdated_at. See Capital Allocators → List Capital Allocators.
2026-07-15
Batch deal-share-types endpoint
A new POST /v3/partners/capital-receivers/deal-share-types/ endpoint returns distinct deal-share-type rows across many companies in one paginated request, filtered by a non-empty capital_receiver_uuid in filter (up to 1,000 UUIDs). Each row is a unique (capital_receiver_uuid, deal_uuid, share_class, transaction_type) combination — built for ETL consumers that would otherwise call the per-company deals endpoint once per company. See Capital Receivers → Batch Deal Share Types via POST.
2026-07-14
Founding date exposed as a full date
Partner legal_entity objects now include date_founded (ISO date string, nullable) and date_founded_precision ("year", "month", or "day", nullable) on every entity type — capital receivers, capital allocators, funds, and service providers (list and detail). The integer year_founded field is retained unchanged for backward compatibility.
Capital receivers and funds also accept date_founded as a POST advanced-filter field (gte / lte / range / eq), enabling full-date founding-date queries alongside the existing year-only year_founded filter. The capital-receivers list now orders by the underlying full date; ?ordering=year_founded behavior is unchanged. See Capital Receivers → Common Filter Fields.
Investors — filter by portfolio-company country
GET/POST /v3/partners/investors/ now accept capital_receiver_headquarters_country_iso_alpha3 and capital_receiver_domicile_country_iso_alpha3, scoping results to investors who have transacted in portfolio companies headquartered in — or domiciled in — the specified countries. Both accept comma-separated ISO alpha-3 codes on GET, or an op: in list in a POST body. Supplying both filters ANDs them. See Investors → Query Parameters.
Known-zero funding amounts now return null
Funding buckets that compute to a known zero (filed_equity_usd, reported_equity_usd, reported_and_filed_equity_usd, filed_debt_usd, reported_debt_usd, reported_and_filed_debt_usd, total_funding_usd) now return null rather than a zero amount. This reverses the earlier distinction between unknown and known-zero for these fields: a null amount now means either. Companies whose funding rolls up to zero sort to the end of funding-based orderings in both directions, and are excluded from numeric range filters (gte/lte, total_funding_min/total_funding_max), since null never satisfies a numeric comparison. See Capital Receivers → The funding object.
2026-07-10
Growth-% fields capped at ±1000%
Every year-over-year growth-percentage field returned by the Partner API now returns null when the computed change exceeds +1000% or falls below −1000% (values at exactly ±1000% are retained). This affects the annual_*_yoy_growth_pct fields on capital-receiver and capital-allocator financials, and operating_revenue_growth_yoy_pct on the capital-receivers list. Out-of-bound values are treated as null for sorting and filtering as well, so they no longer sort as large numbers or pass numeric range filters. See Capital Receivers → Financials.
Batch POST endpoints for news, AUM, and fund performance
Three more POST endpoints extend the batch-export pattern to child records that previously had only per-parent GET routes. Each takes a non-empty in filter on the parent UUID, accepts up to 1,000 UUIDs per request, is paginated, and adds the parent UUID to every returned row so results can be joined back to their parent.
POST /v3/partners/capital-receivers/news/— batch-fetch news articles across companies bycapital_receiver_uuid. See Capital Receivers → Batch News via POST.POST /v3/partners/capital-allocators/aum/— batch-fetch AUM history across allocators bycapital_allocator_uuid. See Capital Allocators → Batch AUM via POST.POST /v3/partners/funds/performance/— batch-fetch performance across funds byfund_uuid. See Funds → Batch Performance via POST.
A missing or empty UUID filter, more than 1,000 UUIDs, or a malformed UUID returns 400 Bad Request. Access matches the existing per-record endpoints.
Capital allocators list — country filter performance
The capital-allocators list (GET /v3/partners/capital-allocators/) no longer times out when filtering by country. Results are unchanged; only response time improves.
2026-07-09
Sort and filter capital receivers by latest investment date
The capital-receivers list now accepts latest_investment_date — the date of a company’s most recent active deal — as both an ordering key and an advanced POST filter field. Sort with ?ordering=-latest_investment_date or filter with a gte comparison to pull only recently-funded companies (the v3 equivalent of the v2 date_of_last_round sort). It is computed only when you filter or sort on it, so plain list requests are unaffected, and companies with no deals sort last in both directions. See Capital Receivers → Advanced Filter (POST).
2026-07-07
Batch POST endpoints for bulk export
Three new POST endpoints let you fetch child records for many parents in a single request, replacing one-GET-per-record loops for large exports. Each takes a non-empty in filter on the parent UUID, accepts up to 1,000 UUIDs per request, and adds the parent UUID to every returned row so results can be joined back to their parent.
POST /v3/partners/people/roles/— batch-fetch roles across people byperson_uuid. See People → Batch Roles via POST.POST /v3/partners/capital-receivers/financials/— batch-fetch financials bycapital_receiver_uuid. See Capital Receivers → Batch Financials via POST.POST /v3/partners/capital-receivers/deals/— batch-fetch deals bycapital_receiver_uuid. See Capital Receivers → Batch Deals via POST.
A missing or empty UUID filter, more than 1,000 UUIDs, or a malformed UUID returns 400 Bad Request. Access matches the existing per-record endpoints (both Atlas and Allocate).
2026-07-01
⚠️ Breaking: capital receiver funding fields renamed and expanded
This is a breaking change. Field names were removed and renamed with no backward-compatible aliases. Requests that read, filter, or sort by the old names will break — filtering or ordering by a removed name now returns
400 Bad Request, and responses no longer contain the old keys. Update your integration before this release reaches you.
The funding object on the capital-receiver detail response has been standardized (a hard cutover — the old field names are gone, with no aliases):
total_funding_amount_usd→total_funding_usdequity_funding_amount_usd→ split intoreported_and_filed_equity_usd,filed_equity_usd, andreported_equity_usddebt_funding_amount_usd→ split intoreported_and_filed_debt_usd,filed_debt_usd, andreported_debt_usd
The total_funding_amount_usd filter and ordering key was renamed to total_funding_usd to match the response field; the old name now returns 400 Bad Request. latest_valuation_usd is unchanged. Filtering, ordering, and the response body now use one identical set of names.
Semantics also changed: null now means unknown while a zero amount means known-zero; public-listed companies return null for all funding and valuation amounts (but keep funding_status); and funding totals now count all primary funding regardless of deal subtype or type. See Capital Receivers → The funding object.
Per-plan endpoint access documented
Added a Plans & Access page listing every endpoint and whether it’s included with the Atlas or Allocate plan. Notable differences: Funds and capital-allocator LP commitments are Atlas-only, while the capital-receivers list/search endpoint is Allocate-only. Custom plans are defined by their own agreements and are not covered by the matrix.
2026-06-29
Rate limits documented
The API is rate limited to 320 requests per rolling 1-minute window. Exceeding the limit returns 429 Too Many Requests with a Retry-After header indicating how long to wait before retrying. See Authentication → Rate Limits for guidance on backoff and retries.
2026-06-19
POST filter body is now strict
On every list endpoint that accepts a POST advanced filter (capital receivers, capital allocators, funds, investors, people, service providers), the request body now accepts only the filters object. search, ordering, limit, and offset must be passed as query parameters — sending them in the body now returns 400 Bad Request instead of being silently ignored.
# Pagination and sorting go on the query string; only filters in the body
curl -X POST "https://api.altdmp.io/v3/partners/capital-receivers/?ordering=-latest_valuation_usd&limit=100" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filters": {"all": [{"op": "eq", "field": "headquarters_country_iso_alpha3", "value": "SGP"}]}}'
Validated ordering
The ordering parameter is now validated against a per-endpoint list of supported fields. An unsupported value returns 400 Bad Request with the list of valid fields, rather than a server error or being silently ignored.
People — country filters
GET /v3/partners/people/ and GET /v3/partners/people/{uuid}/roles/ now accept domicile_country_iso_alpha3 and headquarters_country_iso_alpha3 query parameters, filtering on an associated organization’s country. Both are repeatable or comma-separated (e.g. SGP,USA).
People — multi-word search
The search parameter on people now matches each word independently across given and family name, so a full name such as Shanru Lai matches regardless of word order.
Fund LP commitments — committing parties
GET /v3/partners/funds/{uuid}/commitments/ now returns a transactions[] array on each commitment, exposing the underlying transactions and the committing party (the LP) as transactions[].buyer. The previous top-level transaction_currency, buyer, and seller fields are not part of this endpoint’s response.
Capital receivers — search and registration number
GET /v3/partners/capital-receivers/ search now also matches alternate names, description, and registration number. A registration_number query parameter is available to filter directly by company registration number. is_raising_now is a POST filter field only — not a GET query parameter.
