findContacts
Fuzzy-search contacts by name, phone, email, or address.
Fuzzy-search contacts by name, phone, email, or address. A phone may be its last four digits ("0142"). ARCHIVED contacts are included, marked isArchived (includeArchived: false drops them): one is still in the workspace, never "not in your contacts"; before a write, ask (a form): restore (unarchiveContacts), write anyway, or skip. Rows are QUALIFYING CANDIDATES, relevance-ranked, not matches: each leg (name, phone, email, address) keeps a row only if it clears a trigram-similarity threshold, and survivors are ranked by match quality, not raw score. So an empty result means nothing cleared the bar, and the top row is "the best that did", not the record you named. One shared word clears it: "Northgate Holdings" with no Northgate returns "McNeil Holdings" as totalCount 1. A single result is not evidence of certainty. Before using a contactId in a WRITE, check personName against the name the user said. If it differs, ask which contact they meant rather than write to the best guess: offer the near match as an ASK_USER_QUESTIONS choice naming that person; if you do write, report the name the write echoes, not the one you searched for (see addContactNote).
curl https://server.goliathdata.com/api/v1/call \
-H "Authorization: Bearer $GOLIATH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operationId": "findContacts",
"variables": {
"searchTerm": "<String>"
}
}'import { GoliathClient } from '@goliath-data/sdk'
const goliath = new GoliathClient({
apiKey: process.env.GOLIATH_API_KEY!,
baseUrl: 'https://server.goliathdata.com',
})
const result = await goliath.contacts.findContacts({
searchTerm: '<String>'
})const res = await fetch('https://server.goliathdata.com/api/v1/call', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.GOLIATH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
operationId: 'findContacts',
variables: {
searchTerm: '<String>'
}
}),
})
const { data, errors } = await res.json()limit is clamped to 50.
Variables
The example sends only what the schema requires. Some operations also need one of several optional variables (one filter or another, say); the description above says which.
Default 20.
Default 0.
Default true.
Response
What comes back under data: a list shows as one entry, and a value as its type.
{
"data": {
"contactQuery": {
"getContactIdentityResults": {
"results": [
{
"contactId": "<ID>",
"personName": "…",
"propertyAddress": "…",
"phoneNumber": "…",
"email": "…",
"isArchived": true
}
],
"totalCount": 0,
"hasMore": true
}
}
}
}Errors
unknown_variableA variable the operation does not declare. A typo is refused rather than silently dropped.
unauthorizedNo bearer header, or the key is invalid or revoked.
insufficient_scopeThe key lacks the scope the operation requires.
forbiddenA referenced record does not exist, was deleted, or is outside your organization. The gateway cannot tell those apart.
Behaviour
A read. It rejects an Idempotency-Key header with 400 bad_request.