> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goliathdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deals API

> Read, search, create, update, and archive deals through the Goliath developer API

## About

Programmatic access to your deal flow: fetch and search deals, spot deals
going cold, and create, update, move, or archive deals from your own code.
Pipeline structure (creating pipelines, editing stages) and pipeline
analytics have their own page — see the
[Pipelines API](/developer-api/pipelines).

All operations go through the developer API gateway — one endpoint, called by
`operationId`. If you haven't set up a key yet, start with the
[Developer API Overview](/developer-api/overview).

## Operations

### Reading deals (`READ` scope)

| operationId            | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getDeal`              | Fetch one deal by id — title, value, stage, pipeline, assigned users, linked contacts, derived commission/GCI, team and participant splits, and recorded custom-field values. Use `listDealCustomFields` for definitions with no value.                                                                                                                                                                                                     |
| `findDeals`            | Search deals org-wide — optional `titleContains`, `contactId`, `pipelineId`, `stageId`, `isArchived`, `hasAssignedUsers`, and `userIds` filters. `stageId` reads one pipeline column in a single request; `hasAssignedUsers: false` gets the unowned-deal backlog. Returns a capped page plus the unpaged total, with each deal's assigned users, contacts, and commission figures. Participant splits and custom fields require `getDeal`. |
| `listStalledDeals`     | List deals going cold (no activity for a while), ordered by days inactive, with the linked contact and `inactiveDays`.                                                                                                                                                                                                                                                                                                                      |
| `listDealFiles`        | Files attached to a deal, most-recent-first — `id`, `fileName`, `fileUrl`, `createdAt`. Capped at 25 per call, so page with `offset` when a page comes back full.                                                                                                                                                                                                                                                                           |
| `listDealActivity`     | Page a deal's audit trail, optionally narrowed by `eventTypes` before paging. Covers stage/value/commission/split/assignment/contact/task/file/archive/comment events; title, description, and custom-field edits are not recorded.                                                                                                                                                                                                         |
| `listDealCustomFields` | List a pipeline's custom-field definitions by `pipelineId` — id, name, type (`TEXT` \| `NUMBER` \| `DOLLAR` \| `DATE` \| `LINK` \| `DROPDOWN`), options, `allowMultiple`, `defaultValue`. Deal custom fields are **per-pipeline**. Use each id as the `customFieldId` in the `customFieldValues` input on `createDeal` / `updateDeal`.                                                                                                      |

<Note>
  **findDeals and listStalledDeals are paginated**

  Both return up to **50** rows per call (a larger `limit` is clamped) but take an
  **`offset`** and return `totalCount` + `hasMore`, so you can page through the full
  set: send `offset: 0`, then `offset: 50`, and so on until `hasMore` is `false`. See
  [Result limits & truncation](/developer-api/overview#result-limits--truncation).
</Note>

### Writing deals (`WRITE` scope)

| operationId             | What it does                                                                                                                                                                                                                                                                                                        |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createDeal`            | Create a deal in a stage (`title` + `stageId` required; optional price, close date, links, commission/team/participant splits, and per-pipeline custom-field values). Get stage ids from `listPipelineStages`. The response echoes money and custom fields for read-back.                                           |
| `updateDeal`            | Update a deal — title, price, close date, stage, linked sets, commission/team/participant splits, and custom-field values. Optionally pass `expectedUpdatedAt` as an optimistic-concurrency guard. The response echoes the stored money and custom fields.                                                          |
| `archiveDeal`           | Archive or restore a deal (`isArchived` true/false).                                                                                                                                                                                                                                                                |
| `createDealCustomField` | Create a custom-field definition on a pipeline you **own**: `name` + `type`; `options` required and non-empty for `DROPDOWN`, `allowMultiple`/`defaultValue` optional. A shared pipeline cannot be modified. Applied synchronously; returns the pipeline's field set, so read the new id back by matching the name. |
| `attachDealFile`        | Attach an existing org-owned chat artifact to a deal by `artifactId`. Returns the linked file; raw-byte upload is not exposed.                                                                                                                                                                                      |
| `removeDealFile`        | Detach one file by `fileId` from `listDealFiles`. The stored bytes remain; an absent link is a no-op.                                                                                                                                                                                                               |

<Note>
  **Deal money fields**

  Commission and team split each accept one source: a fixed `*AmountCents` or a
  `*PercentBps`, never both. `commissionCents` is the server-derived GCI to
  report. Participant splits allocate what remains after the team fee. For deal
  custom fields, use the value member that matches the definition type; DOLLAR
  values are plain numbers, not cents, and dropdown values are option labels.
</Note>

<Warning>
  **updateDeal replaces linked sets**

  On `updateDeal`, the `contactIds`, `propertyIds`, and `userIds` arrays
  **replace** the deal's linked set — they do not append. To add one contact,
  send the full existing list plus the new id.
</Warning>

<Note>
  **Guarding against a concurrent edit**

  Pass `expectedUpdatedAt` — the `updatedAt` you got from `getDeal`, `findDeals`,
  or a previous write — to make the update conditional. The write applies only if
  the deal hasn't changed since; otherwise nothing is written and you get
  `CONFLICT`. Use it whenever you decided what to write from a copy you read
  earlier, so a concurrent edit fails loudly instead of being silently
  overwritten.
</Note>

<Warning>
  **Deal file URLs are short-lived**

  `fileUrl` from `listDealFiles` or `attachDealFile` is a time-limited signed
  HTTPS URL. Fetch it promptly, and don't persist or share it — re-read
  `listDealFiles` rather than caching the URL. `attachDealFile` accepts an
  existing artifact id; it is not a raw-byte upload endpoint.
</Warning>

<Note>
  **Organization guard**

  Deal operations are org-guarded: the deal (and any destination stage) must
  belong to a pipeline owned by or shared with your organization, or the call
  returns `403 forbidden`. Pipelines shared with your org through a
  partnership work normally. See
  [Authorization](/developer-api/authorization) for the full
  owned-vs-shared model.
</Note>

## Example

Move a deal to another stage:

```bash theme={null}
# 1. Find the stage id in the deal's pipeline
curl -X POST https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer gsk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "operationId": "listPipelineStages", "variables": { "pipelineId": "PIPELINE_ID" } }'

# 2. Move the deal
curl -X POST https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer gsk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "operationId": "updateDeal", "variables": { "dealId": "DEAL_ID", "input": { "stageId": "STAGE_ID" } } }'
```

Full variable schemas, response shapes, and worked examples for every
operation are available from the
[discovery endpoint](/developer-api/overview#discovering-operations).
