# importContact

Create-or-get a contact migrated from an external system. Keyed on (sourceSystem, externalId): replaying the same record returns the existing contact with wasCreated=false instead of duplicating. Honors historical createdAt/updatedAt (must be in the past) and suppresses live side effects: no workflow triggers, no notifications, no default assignments. The contact field takes the same shape as createContact.

- Call: `POST https://server.goliathdata.com/api/v1/call` with `{ "operationId": "importContact", "variables": {...} }`
- Scope: `IMPORT`
- Type: mutation
- Idempotency: honors `Idempotency-Key` (24 h)
- Rate-limited: no

## Variables

- `input`: `ImportContactInput!` (required)
  - `contact`: `CreateContactInput!` (required). The contact's fields, in the same shape the ordinary createContact mutation accepts.
    - `address`: `AddressInput`
      - `id`: `String`
      - `line1`: `String!` (required)
      - `line2`: `String`
      - `city`: `String!` (required)
      - `state`: `String!` (required)
      - `zip`: `String!` (required)
    - `addressString`: `String`
    - `type`: `PipelineItemType` (one of `LISTING`, `INVESTMENT`, `UNDETERMINED`, `BUYER`)
    - `sellerFirstName`: `String!` (required)
    - `sellerLastName`: `String!` (required)
    - `addMailingAddresses`: `[CreateContactMailingAddressInput!]`
      - `addressString`: `String!` (required). Raw single-line address; resolved via MailingAddressResolutionService (property → address → raw).
      - `propertyElasticsearchId`: `ID`. Instant-duplicate case: the property (Property.id / esId) the user copied this mailing address from: e.g. "use my subject property as the mailing address". When set, the mailing row links straight to that property (no ES search).
      - `verificationStatus`: `VerificationStatus` (one of `VERIFIED`, `UNVERIFIED`, `WRONG`)
      - `ranking`: `Int`. Display order; lower is higher (0 = primary).
    - `addPhoneNumbers`: `[CreateContactPhoneNumberInput!]`
      - `phoneNumber`: `String!` (required)
      - `verificationStatus`: `VerificationStatus!` (required, one of `VERIFIED`, `UNVERIFIED`, `WRONG`)
      - `phoneType`: `PhoneType` (one of `MOBILE`, `RESIDENTIAL`, `LANDLINE`, `UNKNOWN`)
      - `note`: `String`
      - `ranking`: `Int`
    - `addEmails`: `[CreateContactEmailInput!]`
      - `email`: `String!` (required)
      - `verificationStatus`: `VerificationStatus!` (required, one of `VERIFIED`, `UNVERIFIED`, `WRONG`)
      - `note`: `String`
      - `ranking`: `Int`
    - `addCustomFieldValues`: `[CreateContactCustomFieldInput!]`
      - `customFieldId`: `String!` (required)
      - `textValue`: `String`
      - `calendarDate`: `String`. Preferred DATE value as a strict calendar day (YYYY-MM-DD). Do not combine with dateValue.
      - `dateValue`: `DateTime`. Legacy DATE compatibility input. Prefer calendarDate for new clients; do not combine both forms.
      - `numberValue`: `Float`
      - `dropdownSelectedValues`: `[String!]`
    - `subContacts`: `[CreateSubContactInput!]`
      - `name`: `String!` (required)
      - `relation`: `String`
      - `note`: `String`
      - `phoneNumbers`: `[CreateContactPhoneNumberInput!]`
        - `phoneNumber`: `String!` (required)
        - `verificationStatus`: `VerificationStatus!` (required, one of `VERIFIED`, `UNVERIFIED`, `WRONG`)
        - `phoneType`: `PhoneType` (one of `MOBILE`, `RESIDENTIAL`, `LANDLINE`, `UNKNOWN`)
        - `note`: `String`
        - `ranking`: `Int`
      - `emails`: `[CreateContactEmailInput!]`
        - `email`: `String!` (required)
        - `verificationStatus`: `VerificationStatus!` (required, one of `VERIFIED`, `UNVERIFIED`, `WRONG`)
        - `note`: `String`
        - `ranking`: `Int`
    - `addUserGroupIds`: `[ID!]`
  - `sourceSystem`: `String!` (required). Short slug identifying the system this record came from (e.g. "resimpli", "podio"). Lowercase letters, digits, and hyphens only, at most 32 characters. Part of the idempotency key.
  - `externalId`: `String!` (required). The record's id in the source system. At most 256 characters. Part of the idempotency key: importing the same (sourceSystem, externalId) twice returns the existing contact.
  - `createdAt`: `DateTime`. When the record was created in the source system. Must be in the past (any time since 1970). Omitted = now.
  - `updatedAt`: `DateTime`. When the record was last updated in the source system. Must be in the past and not before createdAt; requires createdAt to be provided as well (an omitted createdAt means "now", which would put the update before creation).

## Response (data, an example)

```json
{
  "crmImportMutation": {
    "importContact": {
      "contactId": "<ID>",
      "wasCreated": true
    }
  }
}
```

## Example

```bash
curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "operationId": "importContact",
    "variables": {
      "input": {
        "contact": {
          "sellerFirstName": "<String>",
          "sellerLastName": "<String>"
        },
        "sourceSystem": "<String>",
        "externalId": "<String>"
      }
    }
  }'
```
