Create a deal

POST/v1/crm/deals
Scope: crm:writeIdempotent

Creates a deal. Attach an existing lead with lead_id, or send lead to create one with the deal. Send one or the other, not both. An inline lead is created the way Create a lead does it, and answers the same 409 codes when it can't be.

A lead_id, stage_id or owner_id that isn't in your organization answers 400, not 404, so the response never confirms an ID that belongs to another organization.

Headers

  • AuthorizationstringRequired

    Bearer followed by a space and your API key, for example Bearer vk_….

  • Idempotency-Keystring

    Any unique string, such as a UUID, that makes retrying this request safe. A repeat with the same key for at least 24 hours returns the original response instead of doing the work again. Use a new key for each distinct request.

    at most 255 characters

Request body

  • namestringRequired

    Deal name/title

    at most 2,000 charactersExample "Acme Corp - Enterprise License"
  • expected_close_datestring · date-time or null

    Expected close date

    at most 2,000 charactersExample "2024-03-31T00:00:00+00:00"
  • leadobject or null

    Inline lead data — a new lead will be created and linked to this deal. Cannot be used together with lead_id.

    Show 10 child attributes
    • first_namestringRequired

      Lead's first name

      at most 2,000 charactersExample "Sarah"
    • last_namestringRequired

      Lead's last name

      at most 2,000 charactersExample "Johnson"
    • annual_revenueinteger or null

      Company annual revenue in dollars

      ≥ 0Example 5000000
    • companystring or null

      Company name

      at most 2,000 charactersExample "Acme Corp"
    • company_websitestring or null

      Company website URL

      at most 2,000 charactersExample "https://acmecorp.com"
    • emailstring or null

      Lead's email address (required if linkedin_url not provided)

      at most 2,000 charactersExample "sarah.johnson@acmecorp.com"
    • employeesinteger or null

      Number of employees

      ≥ 0Example 150
    • industrystring or null

      Industry sector

      at most 2,000 charactersExample "Technology"
    • linkedin_urlstring or null

      Lead's LinkedIn profile URL (required if email not provided)

      at most 2,000 charactersExample "https://linkedin.com/in/sarahjohnson"
    • titlestring or null

      Job title

      at most 2,000 charactersExample "VP of Sales"
  • lead_idstring · uuid or null

    ID of an existing lead to associate with this deal

    at most 2,000 charactersExample "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  • metadataobject or null

    Additional metadata

  • notesstring or null

    Deal notes

    at most 2,000 charactersExample "Initial meeting scheduled for next week"
  • owner_idstring · uuid or null

    ID of the deal owner (user)

    at most 2,000 charactersExample "f4a5b6c7-d8e9-0123-f012-456789012345"
  • probabilityinteger or null

    Win probability percentage (0-100)

    ≥ 0≤ 100Example 25
  • stage_idstring · uuid or null

    Initial stage ID (defaults to first stage in pipeline)

    at most 2,000 charactersExample "d2e3f4a5-b6c7-8901-def0-234567890123"
  • valuenumber or null

    Deal value in dollars

    ≥ 0Example 50000

Response

201

  • messagestringRequired
  • dealobjectRequired

    The created deal

    Show 14 child attributes
    • namestringRequired

      Deal name/title

      Example "Acme Corp - Enterprise License"
    • actual_close_datestring · date-time or null

      Actual close date (set when deal is won/lost)

    • created_atstring · date-time or null

      When the deal was created

      Example "2024-01-15T10:30:00+00:00"
    • custom_fieldsobject or null

      Custom fields as key-value pairs

    • expected_close_datestring · date-time or null

      Expected close date

      Example "2024-03-31T00:00:00+00:00"
    • idstring or null

      Deal ID

      Example "e3f4a5b6-c7d8-9012-ef01-345678901234"
    • lead_idstring or null

      Associated lead ID

      Example "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    • metadataobject or null

      Additional metadata

    • notesstring or null

      Deal notes

      Example "Initial meeting scheduled for next week"
    • owner_idstring or null

      ID of the deal owner (user)

      Example "f4a5b6c7-d8e9-0123-f012-456789012345"
    • probabilityinteger or null

      Win probability percentage (0-100)

      Example 75
    • stage_idstring or null

      Current stage ID

      Example "d2e3f4a5-b6c7-8901-def0-234567890123"
    • updated_atstring · date-time or null

      When the deal was last updated

      Example "2024-01-20T14:45:00+00:00"
    • valuenumber or null

      Deal value in dollars

      Example 50000
  • successboolean
    Default true

Errors

Errors share one JSON body: success, error, message, optional details, and request_id.

StatusCodeMeaning
400VALIDATION_ERROR

The request didn't match the endpoint's schema: a missing or malformed field, a bad query parameter, or a value out of range. details.errors lists each failing field with its field, message and type.

400INVALID_LEAD

The lead_id in the request body isn't a lead in your organization. This is a 400 rather than a 404 so the response never confirms an ID that belongs to another organization.

400INVALID_STAGE

The stage_id in the request body isn't a stage in your organization. This is a 400 rather than a 404 for the same reason as INVALID_LEAD.

400INVALID_OWNER

The owner_id in the request body isn't a member of your organization. This is a 400 rather than a 404 for the same reason as INVALID_LEAD.

401UNAUTHORIZED

The Authorization header is missing or malformed, or the API key is unknown or has been deactivated.

401API_KEY_EXPIRED

The API key is past its expiry date. Create a new key in the Victoria AI app.

403TRIAL_LEAD_CAP_REACHED

The organization is on a free trial and has used up its lead quota, so the lead wasn't created. details carries the cap, the number used and the remaining count. Subscribe in the Victoria AI app to add more.

403INSUFFICIENT_SCOPE

The API key doesn't have the scope this endpoint requires, such as leads:write.

403ORGANIZATION_DEACTIVATED

The organization that owns this API key has been deactivated.

409LEAD_ALREADY_EXISTS

A lead with the same email or LinkedIn URL already exists in your organization. From Create a lead, this means the request named no campaign_id to enrol the existing lead in, or raced an identical request. Changing a lead's email or LinkedIn URL to another lead's answers it too. When it's known, details.existing_lead_id identifies the existing lead.

409LEAD_SUPPRESSED

The contact is on your organization's do-not-contact list, so the lead wasn't created, enrolled or updated. details.suppressed_by is email, domain or linkedin_url, and details.value is the entry that matched.

409IDEMPOTENCY_KEY_REUSED

This Idempotency-Key was already used with a different request. Use a new key for each distinct request.

409IDEMPOTENCY_IN_PROGRESS

The first request with this Idempotency-Key is still running. Retry after the Retry-After interval.

413PAYLOAD_TOO_LARGE

The request body is larger than 1 MB.

429RATE_LIMITED

Too many requests for this API key: more than 100 a minute to one endpoint, or 600 a minute in total. Retry after the number of seconds in the Retry-After header. See Rate limits.

500INTERNAL_ERROR

Something failed on our side. The response never includes internal details; quote its request_id when you contact support.

503UPSTREAM_TIMEOUT

A service the API depends on timed out. The request is safe to retry.

503AUTH_UNAVAILABLE

The API key couldn't be checked because the authentication service was unavailable. The request is safe to retry.

Response headers

HeaderDescription
X-Request-ID

Correlation ID for the request, also returned as request_id in error bodies. Send your own X-Request-ID, up to 128 letters, digits, ., _, : or -, and it's used instead.

RateLimit-Limit

Requests allowed to this endpoint per minute.

RateLimit-Remaining

Requests you can still send to this endpoint right now.

RateLimit-Reset

Seconds until the endpoint's full limit is available again.

Retry-After

On a 429, and on 409 IDEMPOTENCY_IN_PROGRESS: seconds to wait before retrying.

Idempotent-Replay

true when the response is a stored replay of an earlier request with the same Idempotency-Key.