API · Platform · Search
Search
Query DSL over indexed resources. Boolean composition, date comparators, and metadata bracket access.
Last updated
TL;DR. POST /v1/<resource>/search with a query string. Grammar supports
AND, OR, quoted literals, date comparators, metadata['<key>']. Indexing lag
up to ~1 minute; use list endpoints for strong read-after-write.
Named list filters (?status=active&jurisdiction=US-DE) get you 80% of queries.
For the other 20% — compliance sweeps, portfolio queries, metadata joins — use the
search API.
Grammar
POST /v1/entities/search
{ "query": "status:'active' AND jurisdiction:'US-DE'" }Terms
field:'value'— exact match. Quotes required for string literals.field:N— unquoted for numbers.field<value,field<=value,field>value,field>=value— range comparators.
Boolean composition
AND— both sides must match (implicit if you omit operators).OR— either side matches.- Parentheses for grouping:
(status:'active' OR status:'registered') AND jurisdiction:'US-DE'.
Dates
Dates use ISO 8601, quoted:
filed_at>'2026-01-01' AND filed_at<'2026-07-01'Relative dates are not supported — compute them client-side.
Metadata
Bracket access on the metadata map:
metadata['fund']:'fund-iii' AND metadata['environment']:'production'Boolean composition works the same over metadata as over real fields.
Supported resources and fields
Each search endpoint documents its own field list on the path description. The common set:
POST /v1/entities/search
status, type, jurisdiction, legal_name, created, updated, portfolio_id,
metadata['<key>'].
POST /v1/stakeholders/search
name, email, role, entity_id, type, created, metadata['<key>'].
POST /v1/filings/search
type, status, entity_id, jurisdiction, due_at, filed_at, accepted_at,
metadata['<key>'].
POST /v1/documents/search
template, entity_id, signed, signed_at, voided, sha256,
metadata['<key>'].
POST /v1/grants/search
entity_id, stakeholder_id, type, status, share_class_id, granted_at,
vesting.cliff_at, metadata['<key>'].
Pagination
Search uses opaque-page pagination, not ID cursors:
{
"query": "status:'active'",
"limit": 50,
"page": "eyJjdXJzb3IiOiJhYmMxMjM..."
}limitdefault 10, max 100.page— pass thenext_pagefrom the previous response.- Responses include
has_more: boolandnext_page: string | null.
Result shape
{
"object": "search_result",
"data": [ /* resources */ ],
"has_more": true,
"url": "/v1/entities/search",
"next_page": "eyJjdXJzb3IiOiJkZWY0NTY...",
"total_count": null
}total_count is populated only for small result sets — when the index can produce a
reliable count without full iteration. For larger queries, check has_more and
paginate.
Indexing lag
Search reads from an async index that can lag ~1 minute behind the primary store.
If you just created a resource and need to read it back immediately, use the list
endpoint (GET /v1/<resource>?...) — those read from the primary store and are
strongly consistent.
Common patterns
Compliance sweep
"All franchise-tax filings due before July 2026 that haven't been filed yet":
POST /v1/filings/search
{
"query": "type:'franchise_tax' AND status:'pending' AND due_at<'2026-07-01'"
}Portfolio rollup with metadata
"All active Delaware C-Corps in fund III":
POST /v1/entities/search
{
"query": "status:'active' AND type:'c_corp' AND jurisdiction:'US-DE' AND metadata['fund']:'fund-iii'"
}Unsigned grants for cleanup
"Grants issued 30+ days ago that still aren't signed":
POST /v1/grants/search
{
"query": "status:'issued' AND granted_at<'2026-03-22'"
}Search vs. list
| If you need to… | Use |
|---|---|
Find resources by named field (status, jurisdiction) | List (GET /v1/<resource>?...) |
| Compose boolean conditions (AND, OR, parentheses) | Search |
| Filter by metadata key | Either (list for exact match, search for composition) |
| Read a resource immediately after writing it | List (strongly consistent) |
| Sweep a portfolio of 500+ entities | Search |
Limits
- 100 results per page, 10,000 results per query (cap to protect the index).
- 1,000 search requests per minute per live key (burst 50/sec).
- Query strings up to 2,048 characters.