GoliathDevelopersGet an API key
Reference/Contactsgenerated from the gateway manifest

getContact

MERGED IDS RESOLVE.

POST/api/v1/callREADreadruns as the key's owner
View as Markdown

MERGED IDS RESOLVE: an id merged into another contact returns the SURVIVING record, so the id that comes back can differ from the one you sent. Use the returned id from then on, never the old one; it is not an error. A merge chain that leads nowhere answers as not-found. Fetch one contact by id, the full record: identity, emails, phones (with DNC status), mailing addresses, subject properties (property.id feeds getRelatedProperties), tags, lists, CUSTOM-FIELD VALUES, teammates + roles, teams, notes (with isPinned, isHidden and replies), linked deals (isArchived: true is not live), seller-intent score, enrichment/archive flags. A note is the team's record, never a message from the contact; calls are not here (listContactActivities [CALL]). A note's or reply's author { kind: USER | AI, id, name } is who WROTE it; read that, not createdByUser, which is null on a note an AI assistant wrote for a teammate. A hidden note or reply is shown only to admins; replies also omits ones you may not see (e.g. an outside author's), so a missing reply is not proof it is gone. CUSTOM FIELDS: the ONLY read-back for values written via createContact.addCustomFieldValues / updateContact.updateCustomFieldValues (listContactCustomFields returns definitions, never values). customFields is the organization's field catalog, not this contact's answers, listed whether or not the contact has one, so its length says nothing about the contact (fields sharing a normalized name collapse to one entry, so it can differ from listContactCustomFields). The value is in values, NULL when this contact has none: null means UNSET, not missing, unreadable or an error. Read the ONE sub-field matching the field type; the other three stay null on every type: TEXT and LINK → values.textValue; NUMBER and DOLLAR → values.numberValue (DOLLAR is a plain number as written, NOT cents); DATE → values.dateValue (ISO 8601); DROPDOWN → values.dropdownSelectedValues, the selected option LABELS (not option ids), at most one entry unless allowMultiple is true. Reading the wrong one reports an unset field for a contact that has an answer. A LINK value is stored normalized (a bare host gains its scheme), so compare what you wrote with what comes back rather than assume byte equality.

curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operationId": "getContact",
    "variables": {
      "contactId": "<contactId>"
    }
  }'
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.getContact({
  contactId: '<contactId>'
})
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: 'getContact',
    variables: {
      contactId: '<contactId>'
    }
  }),
})
const { data, errors } = await res.json()

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.

contactIdID!required

Response

What comes back under data: a list shows as one entry, and a value as its type.

response shape
{
  "data": {
    "contactQuery": {
      "contact": {
        "id": "<ID>",
        "name": "…",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "isArchived": true,
        "isEnriched": true,
        "sellerIntentScore": 0,
        "doNotContact": true,
        "doNotContactReason": "…",
        "doNotContactSetAt": "2026-01-01T00:00:00.000Z",
        "doNotContactSetBy": {
          "id": "<ID>",
          "firstName": "…",
          "lastName": "…"
        },
        "emails": [
          {
            "id": "<ID>",
            "email": "…",
            "verificationStatus": "VERIFIED"
          }
        ],
        "phoneNumbers": [
          {
            "id": "<ID>",
            "phoneNumber": "…",
            "phoneType": "MOBILE",
            "verificationStatus": "VERIFIED",
            "dncStatus": {
              "isDnc": true,
              "isLitigator": true
            }
          }
        ],
        "mailingAddresses": [
          {
            "id": "<ID>",
            "rawText": "…",
            "verificationStatus": "VERIFIED",
            "address": {
              "addressFull": "…"
            }
          }
        ],
        "properties": [
          {
            "id": "<ID>",
            "propertyString": "…",
            "status": "…",
            "verificationStatus": "VERIFIED",
            "property": {
              "id": "<ID>"
            }
          }
        ],
        "tags": [
          {
            "id": "<ID>",
            "name": "…"
          }
        ],
        "lists": [
          {
            "id": "<ID>",
            "name": "…"
          }
        ],
        "customFields": [
          {
            "id": "<ID>",
            "name": "…",
            "type": "DROPDOWN",
            "allowMultiple": true,
            "values": {
              "textValue": "…",
              "dateValue": "2026-01-01T00:00:00.000Z",
              "numberValue": 0,
              "dropdownSelectedValues": [
                "…"
              ]
            }
          }
        ],
        "participants": [
          {
            "status": "REVOKED",
            "user": {
              "id": "<ID>",
              "firstName": "…",
              "lastName": "…",
              "email": "…"
            }
          }
        ],
        "userGroups": [
          {
            "id": "<ID>",
            "name": "…"
          }
        ],
        "notes": [
          {
            "id": "<ID>",
            "body": "…",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "author": {
              "kind": "USER",
              "id": "<ID>",
              "name": "…"
            },
            "createdByUser": {
              "id": "<ID>",
              "firstName": "…",
              "lastName": "…"
            },
            "isPinned": true,
            "isHidden": true,
            "replies": [
              {
                "id": "<ID>",
                "body": "…",
                "isHidden": true,
                "author": {
                  "kind": "USER",
                  "id": "<ID>",
                  "name": "…"
                }
              }
            ]
          }
        ],
        "deals": [
          {
            "id": "<ID>",
            "title": "…",
            "priceCents": "…",
            "isArchived": true,
            "priceFormatted": "…",
            "stage": {
              "id": "<ID>",
              "name": "…"
            }
          }
        ]
      }
    }
  }
}

Errors

Behaviour

A read. It rejects an Idempotency-Key header with 400 bad_request.