GoliathDevelopersGet an API key
Reference/Dealsgenerated from the gateway manifest

createDeal

Create a deal in a pipeline stage.

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

Create a deal in a pipeline stage. Requires title and stageId (listPipelineStages); optional priceCents, closeDate, contact/property/user ids. Entering the stage can text or email a real person, as an updateDeal move can: confirm as updateDeal says. The stage must be in a pipeline owned by or shared with your organization, and any linked contactIds/userIds must belong to your organization. userIds is the deal’s TEAM, and My deals shows only deals the viewer is on. The app’s Create Deal form puts its creator on the team, so when acting for a person include the key owner (getMyProfile) unless they name a different team. MONEY AND CUSTOM FIELDS (the whole input is one variable, so discovery cannot expand it). Commission takes ONE source per side, never both: commissionAmountCents (a fixed dollar figure in cents) XOR commissionPercentBps (basis points (300 = 3%) applied to priceCents); and teamSplitAmountCents XOR teamSplitPercentBps (basis points applied to the resulting COMMISSION, not the price). Sending both halves of a pair with values is rejected; sending one explicitly as null CLEARS that side. The server derives commissionCents (GCI) and returns it: read it there. A percent re-derives when priceCents changes; an amount does not. participantSplits is [{ userId, splitAmountCents | splitPercentBps }] allocating what remains after the team fee, and it must not exceed the pool. customFieldValues is [{ customFieldId (from listDealCustomFields (deal fields are PER-PIPELINE), and exactly ONE of textValue (TEXT/LINK) | numberValue (NUMBER/DOLLAR, a plain number, NOT cents) | dateValue (DATE, ISO 8601) | dropdownSelectedValues (DROPDOWN) the option LABEL strings, not option ids) matching the field’s type }]. The response echoes the money and custom fields: confirm the write from it.

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": "createDeal",
    "variables": {
      "input": {
        "title": "<String>",
        "stageId": "<stageId>"
      }
    }
  }'
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.deals.createDeal(
  {
    input: {
      title: '<String>',
      stageId: '<stageId>'
    }
  },
  { 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: 'createDeal',
    variables: {
      input: {
        title: '<String>',
        stageId: '<stageId>'
      }
    }
  }),
})
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.

inputCreatePipelineItemInput!required
titleString!required
stageIdID!required
descriptionString
priceCentsBigInt
commissionAmountCentsBigInt
commissionPercentBpsInt
teamSplitAmountCentsBigInt
teamSplitPercentBpsInt
participantSplits[PipelineItemParticipantSplitInput!]
closeDateDateTime
propertyIds[ID!]
propertyStrings[String!]
contactIds[ID!]
userIds[ID!]
fileIds[ID!]
customFieldValues[PipelineItemCustomFieldValueInput!]
Every field, all the way down
variables
[
  {
    "name": "input",
    "type": "CreatePipelineItemInput!",
    "required": true,
    "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
          }
        ]
      }
    ]
  }
]

Response

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

response shape
{
  "data": {
    "dealMutation": {
      "createDeal": {
        "id": "<ID>",
        "title": "…",
        "priceCents": "…",
        "closeDate": "2026-01-01T00:00:00.000Z",
        "isArchived": true,
        "updatedAt": "2026-01-01T00:00:00.000Z",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "commissionCents": "…",
        "commissionAmountCents": "…",
        "commissionPercentBps": 0,
        "teamSplitAmountCents": "…",
        "teamSplitPercentBps": 0,
        "participantSplits": [
          {
            "user": {
              "id": "<ID>",
              "firstName": "…",
              "lastName": "…"
            },
            "splitAmountCents": "…",
            "splitPercentBps": 0
          }
        ],
        "customFieldValues": [
          {
            "id": "<ID>",
            "textValue": "…",
            "dateValue": "2026-01-01T00:00:00.000Z",
            "numberValue": 0,
            "dropdownSelectedValues": [
              "…"
            ],
            "dealCustomField": {
              "id": "<ID>",
              "name": "…",
              "type": "DROPDOWN"
            }
          }
        ],
        "stage": {
          "id": "<ID>",
          "name": "…"
        },
        "pipeline": {
          "id": "<ID>",
          "name": "…"
        },
        "contacts": [
          {
            "id": "<ID>",
            "name": "…"
          }
        ],
        "properties": [
          {
            "id": "<ID>",
            "address": {
              "addressFull": "…"
            }
          }
        ]
      }
    }
  }
}

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 →