GoliathDevelopersGet an API key
Reference/Crm Importgenerated from the gateway manifest

importDeal

Create-or-get a deal migrated from an external system.

POST/api/v1/callIMPORTidempotent · 24 hruns as the key's owner
View as Markdown

Create-or-get a deal migrated from an external system. Keyed on (sourceSystem, externalId): replaying the same record returns the existing deal with wasCreated=false instead of duplicating. Honors historical createdAt/updatedAt (must be in the past) and suppresses live side effects: no workflow triggers (neither DEAL stage-entered nor per-contact deal-created events fire), no notifications. The deal field takes the same shape as createDeal: stageId from listPipelineStages, linked contacts/users by id, propertyStrings for unresolved addresses, customFieldValues from listDealCustomFields. The create is atomic: the deal row and every link (contacts, properties, users, splits) commit together or not at all, so a failed call leaves nothing behind and a retry re-creates cleanly. A replay (wasCreated=false) never rewrites the existing deal (links and edits made since the import are left alone) with one deliberate exception: custom-field values are filled where still MISSING (crash-retry recovery for the one write applied after the create) and never overwritten.

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": "importDeal",
    "variables": {
      "input": {
        "sourceSystem": "<String>",
        "externalId": "<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.crmImport.importDeal(
  {
    input: {
      sourceSystem: '<String>',
      externalId: '<String>'
    }
  },
  { idempotencyKey: crypto.randomUUID() },
)
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',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    operationId: 'importDeal',
    variables: {
      input: {
        sourceSystem: '<String>',
        externalId: '<String>'
      }
    }
  }),
})
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.

inputImportPipelineItemInput!required
pipelineItemCreatePipelineItemInput

The deal's fields, in the same shape the ordinary createDeal mutation accepts (stageId from listPipelineStages; contacts/properties/users linked by id; customFieldValues from listDealCustomFields).

dealCreatePipelineItemInput
sourceSystemString!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.

externalIdString!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 deal.

createdAtDateTime

When the record was created in the source system. Must be in the past (any time since 1970). Omitted = now.

updatedAtDateTime

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). Also stamps the deal's stage-entry timestamp (lastStageChangeAt): source systems don't export per-stage move history, so the deal is recorded as sitting in its stage since updatedAt: falling back to createdAt, then to the import time when neither is provided.

Every field, all the way down
variables
[
  {
    "name": "input",
    "type": "ImportPipelineItemInput!",
    "required": true,
    "description": null,
    "defaultValue": null,
    "fields": [
      {
        "name": "pipelineItem",
        "type": "CreatePipelineItemInput",
        "required": false,
        "description": "The deal's fields, in the same shape the ordinary createDeal mutation accepts (stageId from listPipelineStages; contacts/properties/users linked by id; customFieldValues from listDealCustomFields).",
        "defaultValue": null,
        "fields": [
          {
            "name": "title",
            "type": "String!",
            "required": true,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "stageId",
            "type": "ID!",
            "required": true,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "description",
            "type": "String",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "priceCents",
            "type": "BigInt",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "commissionAmountCents",
            "type": "BigInt",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "commissionPercentBps",
            "type": "Int",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "teamSplitAmountCents",
            "type": "BigInt",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "teamSplitPercentBps",
            "type": "Int",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "participantSplits",
            "type": "[PipelineItemParticipantSplitInput!]",
            "required": false,
            "description": null,
            "defaultValue": null,
            "fields": [
              {
                "name": "userId",
                "type": "ID!",
                "required": true,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "splitAmountCents",
                "type": "BigInt",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "splitPercentBps",
                "type": "Int",
                "required": false,
                "description": null,
                "defaultValue": null
              }
            ]
          },
          {
            "name": "closeDate",
            "type": "DateTime",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "propertyIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "propertyStrings",
            "type": "[String!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "contactIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "userIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "fileIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "customFieldValues",
            "type": "[PipelineItemCustomFieldValueInput!]",
            "required": false,
            "description": null,
            "defaultValue": null,
            "fields": [
              {
                "name": "customFieldId",
                "type": "ID!",
                "required": true,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "textValue",
                "type": "String",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "dateValue",
                "type": "DateTime",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "numberValue",
                "type": "Float",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "dropdownSelectedValues",
                "type": "[String!]",
                "required": false,
                "description": null,
                "defaultValue": null
              }
            ]
          }
        ]
      },
      {
        "name": "deal",
        "type": "CreatePipelineItemInput",
        "required": false,
        "description": null,
        "defaultValue": null,
        "fields": [
          {
            "name": "title",
            "type": "String!",
            "required": true,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "stageId",
            "type": "ID!",
            "required": true,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "description",
            "type": "String",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "priceCents",
            "type": "BigInt",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "commissionAmountCents",
            "type": "BigInt",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "commissionPercentBps",
            "type": "Int",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "teamSplitAmountCents",
            "type": "BigInt",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "teamSplitPercentBps",
            "type": "Int",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "participantSplits",
            "type": "[PipelineItemParticipantSplitInput!]",
            "required": false,
            "description": null,
            "defaultValue": null,
            "fields": [
              {
                "name": "userId",
                "type": "ID!",
                "required": true,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "splitAmountCents",
                "type": "BigInt",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "splitPercentBps",
                "type": "Int",
                "required": false,
                "description": null,
                "defaultValue": null
              }
            ]
          },
          {
            "name": "closeDate",
            "type": "DateTime",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "propertyIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "propertyStrings",
            "type": "[String!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "contactIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "userIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "fileIds",
            "type": "[ID!]",
            "required": false,
            "description": null,
            "defaultValue": null
          },
          {
            "name": "customFieldValues",
            "type": "[PipelineItemCustomFieldValueInput!]",
            "required": false,
            "description": null,
            "defaultValue": null,
            "fields": [
              {
                "name": "customFieldId",
                "type": "ID!",
                "required": true,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "textValue",
                "type": "String",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "dateValue",
                "type": "DateTime",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "numberValue",
                "type": "Float",
                "required": false,
                "description": null,
                "defaultValue": null
              },
              {
                "name": "dropdownSelectedValues",
                "type": "[String!]",
                "required": false,
                "description": null,
                "defaultValue": null
              }
            ]
          }
        ]
      },
      {
        "name": "sourceSystem",
        "type": "String!",
        "required": true,
        "description": "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.",
        "defaultValue": null
      },
      {
        "name": "externalId",
        "type": "String!",
        "required": true,
        "description": "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 deal.",
        "defaultValue": null
      },
      {
        "name": "createdAt",
        "type": "DateTime",
        "required": false,
        "description": "When the record was created in the source system. Must be in the past (any time since 1970). Omitted = now.",
        "defaultValue": null
      },
      {
        "name": "updatedAt",
        "type": "DateTime",
        "required": false,
        "description": "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). Also stamps the deal's stage-entry timestamp (lastStageChangeAt): source systems don't export per-stage move history, so the deal is recorded as sitting in its stage since updatedAt: falling back to createdAt, then to the import time when neither is provided.",
        "defaultValue": null
      }
    ]
  }
]

Response

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

response shape
{
  "data": {
    "crmImportMutation": {
      "importDeal": {
        "dealId": "<ID>",
        "wasCreated": true
      }
    }
  }
}

Errors

Idempotency

Send an Idempotency-Key of 1 to 255 characters. A finished request retried with the same key replays its stored response, marked Idempotency-Replayed: true; one still in flight returns 409 idempotency_conflict. Keys expire after 24 hours. Write without fear →