WundertreOS

Create deal

Create a new deal in a pipeline, optionally linked to a contact or company.

POST/api-deals
Try it
POST

Create an API key in your workspace under Settings → Integrations & API.

Requires the crm:write scope (the legacy contacts:write alias also works). Returns 201 Created with the new deal.

Request body

Only title is required. If you omit pipeline_id the deal lands in your organization's default pipeline; if you omit stage_id it lands in that pipeline's first stage. Use List pipelines to look up IDs when you want to target a specific pipeline or stage. Unknown fields are ignored.

Body
NameTypeDescription
titlerequiredstringDeal name as it appears on the board.
valuenumber | stringMonetary value. Strings such as "$1,200.50" are parsed; an empty string or omitted value is stored as 0.
currencystringISO 4217 code (e.g. USD). Upper-cased on save. Defaults to USD.
contact_iduuidLink to a contact. Must belong to your organization.
company_iduuidLink to a company. Must belong to your organization.
pipeline_iduuidPipeline to create the deal in. Defaults to the org's default pipeline.
stage_iduuidStage within that pipeline. Defaults to the pipeline's first stage. Must belong to the resolved pipeline.
expected_close_datestring (ISO 8601 date)e.g. 2026-06-30.
notesstringFree-text notes on the deal.

Example request

bash
curl -X POST \
  'https://api.wundertreos.com/functions/v1/api-deals' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Acme — Annual plan",
    "value": 12000,
    "currency": "USD",
    "contact_id": "c8b1f3a0-4d2e-4f9a-9b1c-2d4e5f6a7b8c",
    "expected_close_date": "2026-06-30"
  }'

Response

Returns the created deal (same shape as Get deal):

json
{
  "data": {
    "id": "d1e2f3a4-1111-2222-3333-444455556666",
    "org_id": "a1b2c3d4-1111-2222-3333-444455556666",
    "contact_id": "c8b1f3a0-4d2e-4f9a-9b1c-2d4e5f6a7b8c",
    "company_id": null,
    "pipeline_id": "p1a2b3c4-1111-2222-3333-444455556666",
    "stage_id": "s1a2b3c4-1111-2222-3333-444455556666",
    "title": "Acme — Annual plan",
    "value": 12000,
    "currency": "USD",
    "expected_close_date": "2026-06-30",
    "assigned_to": null,
    "notes": null,
    "won_at": null,
    "lost_at": null,
    "lost_reason": null,
    "created_at": "2026-05-17T14:00:00Z",
    "updated_at": "2026-05-17T14:00:00Z",
    "created_by": "u1b1f3a0-4d2e-4f9a-9b1c-2d4e5f6a7b8c"
  }
}

Creating a deal emits a deal.created webhook event and fires any Deal created workflow triggers, exactly as if it had been created in the app.

Errors

StatuserrorWhen
400invalid_requesttitle is missing; value is not numeric; pipeline_id, stage_id, contact_id, or company_id doesn't exist in your organization; the org has no pipelines yet; or the body is not valid JSON.
403forbiddenThe credential lacks the crm:write scope.
500server_errorDatabase write failed.
Creating a deal that is already closed

There is no "create as won" flag. Create the deal, then call Update deal with { "status": "won" } — that moves it to the pipeline's won stage and stamps won_at in one request.