On this page
Search records through the API
Search a Golden entity with record-shaped criteria or free text, discover what an entity can be searched by, and interpret paged results safely.
Golden searches within one entity, and offers two ways in:
| Operation | For |
|---|---|
POST /api/golden/{entity}/search | A structured query: a record fragment whose fields belong to the entity dataset |
POST /api/golden/{entity}/search/text | A free-text query: one line, the way a search bar works |
Record search allows VIEWER, STEWARD, and ADMIN, within their data grants.
Examples use the Aurelia Utilities sample,
whose entity is sample-customer-entity.
Discover searchable fields
Do this before hard-coding field names. The answer is generated from the entity’s indexer, and it is the same answer the web application uses to build its search bar.
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer ${GOLDEN_TOKEN}" \
"${GOLDEN_URL}/api/golden/sample-customer-entity/search/capabilities"
{
"entity": "sample-customer-entity",
"searchable": true,
"freeTextIndexed": true,
"fields": [
{ "mapping": "by-tax-id", "columns": ["taxId"], "matching": "EXACT", "combined": false, "freeText": true },
{ "mapping": "by-email", "columns": ["email"], "matching": "EXACT", "combined": false, "freeText": true },
{ "mapping": "by-phone", "columns": ["phone"], "matching": "EXACT", "combined": false, "freeText": true },
{ "mapping": "by-name-postcode", "columns": ["fullName", "postcode"], "matching": "FUZZY", "combined": true, "freeText": true }
]
}
combined: true means the mapping’s columns form one key together — searching
fullName alone does not use by-name-postcode. Use this response to adapt search controls to the entity’s current mappings.
Structured search
curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer ${GOLDEN_TOKEN}" \
--header "Content-Type: application/json" \
--data '{
"record": { "taxId": "12345678Z" },
"options": {},
"pageNumber": 0,
"pageSize": 10
}' \
"${GOLDEN_URL}/api/golden/sample-customer-entity/search"
record is required and cannot be empty. Search behavior follows the entity’s
indexer, including which fields bring candidates
together and how text is normalized.
The request can also carry:
| Field | Default | Purpose |
|---|---|---|
transformation | None | Apply a named transformation to the submitted record before searching |
entity | false | Include entity information in the response |
filter | None | A metadata filter, the same one the record page sends, applied to the records reached |
tableType | Both | TABLE searches only current records; HISTORY only historical ones |
pageSize | 10 | At most 1000. A larger value is a 400, not a silent truncation |
options | Defaults | See below |
Search options
| Option | Default | Effect |
|---|---|---|
identity | true | Search by identity when the submitted record carries one |
provenance | true | Look up a free-text term as a source record identifier (_source._src_id) |
exact | EXACT | Exact-match type: EXACT, PREFIX, SUFFIX, or INFIX |
combine | ANY | How several filled fields combine: ANY or ALL |
fieldModes | Per mapping | Per-column probe mode: MAPPING, EXACT, or SIMILAR |
fuzzy | true | Also consider fuzzy matches |
fuzzyMaximumTypos | 2 | Maximum typographical errors for fuzzy search |
geo | true | Also consider geographic matches |
geoPrecision | Default | Geographic area precision, L1–L10 |
geoSteps | 1 | Neighboring geographic steps |
radiusMeters | 0 | Radius for a geographic search. Zero or negative falls back to geoPrecision |
maximumResults | -1 | Result cap; -1 means no count limit |
maximumDuration | 5 seconds | Search processing time limit |
combine defaults to ANY in the API. The advanced web form sends ALL.
With ANY, adding another field can broaden the results; with ALL, every
filled field must match. Set this option explicitly.
fieldModes is the API form of the advanced form’s per-field Exact /
Similar switch. A column absent from the map is probed with its mapping’s
own matching type. It is meaningful only for structured search: free text
always probes by word similarity.
The five-second default duration means a broad search is time-bounded. Choose a duration appropriate to the workflow rather than assuming every search is exhaustive.
Free-text search
curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer ${GOLDEN_TOKEN}" \
--header "Content-Type: application/json" \
--data '{"query":"Ana Garcia Munoz","pageNumber":0,"pageSize":10}' \
"${GOLDEN_URL}/api/golden/sample-customer-entity/search/text"
The field is query, not text. Sending text answers “Invalid null
or empty search query”.
Whitespace separates terms and double quotes hold a phrase together. Every term
is probed against every searchable field, the record identifier, and source
identifiers when provenanceSearchable is true, and a
record matching more terms ranks higher.
Two behaviors have no equivalent in structured search:
- History is included in the same result, with a merged record resolved forward to the record that survived it.
similaritybounds the word-similarity threshold. It must be below1.0; a value at or above it is a400, because word similarity can only reach 1.0 on a whole-key match.
The query above returns three records from the sample:
| Source | Reference | Full name | Tax ID | |
|---|---|---|---|---|
| CRM | CRM-DUP-0001 | ANA Garcaí Muñoz | 12345678Z | Ana.Garcia@Example.com |
| BILLING | BILL-0001 | Ana Garcia Munoz | (empty) | ana.garcia@ |
| CRM | CRM-0001 | Ana García Muñoz | 12345678Z | ana.garcia@example.com |
A structured search on taxId returns only two: the billing record has no tax
identifier. Free-text search can find this record through its name even
though that identifier is absent.
Read the response
| Field | Meaning |
|---|---|
search | The record criteria Golden used, after any requested transformation |
result | Records on the current page |
count | Total matching record count |
truncated | The search stopped at its limit. The result is part of the answer |
page | Current pagination information |
entity | Optional entity information when requested |
Page until the page information shows no remaining results. Check
truncated: a narrower or longer term is what fixes it, not another page.
Results can carry _search metadata describing why a record was returned:
| Field | Meaning |
|---|---|
index | Indexer mapping that found the result |
match | Matched text, normalized |
type | ID, SOURCE, EXACT, PREFIX, SUFFIX, INFIX, FUZZY, FUZZY_LSH, GEOGRAPHIC, or NONE |
rank | Relative match-strength signal |
exact | Whether the match was exact |
origin | How the record was reached, which is not the same question as what matched it |
Search result origin
| Value | Meaning |
|---|---|
DIRECT | The record’s own value for that mapping is what matched |
CLUSTER | The record came in through a bucket connected to the one that matched. Its own value may be nothing like the search term |
HISTORY | The record lives in the history relation. It is not current |
MERGED_FORWARD | The record is current and was reached through a record merged into it. The matching value belonged to the absorbed record and is in none of this record’s columns. sourceId names the record it came through |
For CLUSTER and MERGED_FORWARD, explain that the result was reached
through another record rather than through a direct match on its own values.
A MERGED_FORWARD result is the current surviving record, not a history row.
Use the evidence to understand the lookup; do not reproduce ranking behavior
from rank, and do not use it for identity decisions. That is what the
classifier and the duplicate review are for. See the
record metadata reference.
If search returns nothing
Check that:
- the entity identifier and field names are correct —
search/capabilitiessettles both; - the entity is enabled and its synchronization has completed;
- the relevant indexer mapping participates in search;
combineis the combination you meant;- normalization and matching options suit the submitted value; and
- the caller is using the intended environment and credential.
An empty result means this search found no matching record under these
options. If the question is whether a raw row exists, inspect the entity’s
table separately with Query table data.