# Growth

Growth projects: the Company brain, campaigns, research runs and data-provider keys.

Generated from contract version `1.0.0` — the same document [`/v1/api/openapi.json`](/api/openapi/) serves.

## Prerequisites

- An API key in `x-api-key`, or a browser session cookie
- `X-Organization-Id` naming the workspace to act in, unless the session already has an active one
- The base URL for your deployment, `https://server.hlix.ai` by default

## Operations

| Method | Path | Operation |
| --- | --- | --- |
| `GET` | `/v1/api/growth/chains` | [Each capability's data-provider order and how each provider did in the last 7 days](#each-capabilitys-data-provider-order-and-how-each-provider-did-in-the-last-7-days) |
| `PUT` | `/v1/api/growth/chains/{capability}` | [Set the order a capability tries its providers in, or go back to the default](#set-the-order-a-capability-tries-its-providers-in-or-go-back-to-the-default) |
| `POST` | `/v1/api/growth/chains/find_email/compare` | [Run two email finders on the same sample of the workspace's leads](#run-two-email-finders-on-the-same-sample-of-the-workspaces-leads) |
| `GET` | `/v1/api/growth/citable-projects` | [List the finished delivery projects a growth brain may quote](#list-the-finished-delivery-projects-a-growth-brain-may-quote) |
| `GET` | `/v1/api/growth/index` | [The size of Hlix's shared company index and how many of the workspace's companies it supplied](#the-size-of-hlixs-shared-company-index-and-how-many-of-the-workspaces-companies-it-supplied) |
| `PATCH` | `/v1/api/growth/leads/{leadId}` | [Disqualify a lead or put it back in line](#disqualify-a-lead-or-put-it-back-in-line) |
| `POST` | `/v1/api/growth/leads/{leadId}/reply` | [Answer a lead in their thread from the mailbox that wrote to them](#answer-a-lead-in-their-thread-from-the-mailbox-that-wrote-to-them) |
| `GET` | `/v1/api/growth/leads/{leadId}/thread` | [Show a lead's whole email thread, drafts included](#show-a-leads-whole-email-thread-drafts-included) |
| `GET` | `/v1/api/growth/mailboxes` | [List the workspace's sending mailboxes with their warm-up and today's sends](#list-the-workspaces-sending-mailboxes-with-their-warm-up-and-todays-sends) |
| `DELETE` | `/v1/api/growth/mailboxes/{mailboxId}` | [Disconnect a mailbox and revoke its access](#disconnect-a-mailbox-and-revoke-its-access) |
| `PATCH` | `/v1/api/growth/mailboxes/{mailboxId}` | [Change a mailbox's daily limit or warm-up start, or pause and resume it](#change-a-mailboxs-daily-limit-or-warm-up-start-or-pause-and-resume-it) |
| `GET` | `/v1/api/growth/mailboxes/{mailboxId}/dns` | [Check the mailbox domain's SPF, DKIM and DMARC records](#check-the-mailbox-domains-spf-dkim-and-dmarc-records) |
| `POST` | `/v1/api/growth/mailboxes/connect` | [Start connecting a Google or Microsoft mailbox to send from](#start-connecting-a-google-or-microsoft-mailbox-to-send-from) |
| `PATCH` | `/v1/api/growth/messages/{messageId}` | [Sort a reply by hand](#sort-a-reply-by-hand) |
| `POST` | `/v1/api/growth/messages/{messageId}/approve` | [Approve a drafted email, optionally edited, so it sends](#approve-a-drafted-email-optionally-edited-so-it-sends) |
| `POST` | `/v1/api/growth/messages/{messageId}/resolve` | [Record whether an email whose delivery was unknown went out](#record-whether-an-email-whose-delivery-was-unknown-went-out) |
| `PATCH` | `/v1/api/growth/plays/{playId}` | [Edit or launch a campaign](#edit-or-launch-a-campaign) |
| `POST` | `/v1/api/growth/projects` | [Create a growth project from a website and start its research run](#create-a-growth-project-from-a-website-and-start-its-research-run) |
| `GET` | `/v1/api/growth/projects/{projectId}` | [Show a growth project's brain, campaigns and last run](#show-a-growth-projects-brain-campaigns-and-last-run) |
| `PUT` | `/v1/api/growth/projects/{projectId}/brain` | [Replace the Company brain](#replace-the-company-brain) |
| `GET` | `/v1/api/growth/projects/{projectId}/inbox` | [List a growth project's email threads, one per lead](#list-a-growth-projects-email-threads-one-per-lead) |
| `POST` | `/v1/api/growth/projects/{projectId}/lead-lists` | [Upload a lead list to a growth project](#upload-a-lead-list-to-a-growth-project) |
| `GET` | `/v1/api/growth/projects/{projectId}/leads` | [List a growth project's leads with their evidence and provenance](#list-a-growth-projects-leads-with-their-evidence-and-provenance) |
| `POST` | `/v1/api/growth/projects/{projectId}/runs` | [Run the website research again](#run-the-website-research-again) |
| `GET` | `/v1/api/growth/projects/{projectId}/spend` | [Show each campaign's data-provider spend for today and the last 30 days](#show-each-campaigns-data-provider-spend-for-today-and-the-last-30-days) |
| `GET` | `/v1/api/growth/providers` | [List growth data providers and the workspace's key state](#list-growth-data-providers-and-the-workspaces-key-state) |
| `PATCH` | `/v1/api/growth/providers/{provider}` | [Turn a growth provider on or off for the workspace, or change its settings](#turn-a-growth-provider-on-or-off-for-the-workspace-or-change-its-settings) |
| `DELETE` | `/v1/api/growth/providers/{provider}/key` | [Remove the workspace's own key for a growth provider](#remove-the-workspaces-own-key-for-a-growth-provider) |
| `PUT` | `/v1/api/growth/providers/{provider}/key` | [Add or replace the workspace's own key for a growth provider](#add-or-replace-the-workspaces-own-key-for-a-growth-provider) |
| `GET` | `/v1/api/growth/settings` | [The workspace's growth settings and this month's growth spend](#the-workspaces-growth-settings-and-this-months-growth-spend) |
| `PATCH` | `/v1/api/growth/settings` | [Change the hard cap, the sending rules or the booking link](#change-the-hard-cap-the-sending-rules-or-the-booking-link) |
| `GET` | `/v1/api/growth/suppressions` | [List the do-not-contact list](#list-the-do-not-contact-list) |
| `POST` | `/v1/api/growth/suppressions` | [Add addresses and domains to the do-not-contact list](#add-addresses-and-domains-to-the-do-not-contact-list) |
| `DELETE` | `/v1/api/growth/suppressions/{suppressionId}` | [Remove an entry a person added to the do-not-contact list](#remove-an-entry-a-person-added-to-the-do-not-contact-list) |

## Each capability's data-provider order and how each provider did in the last 7 days

`GET /v1/api/growth/chains` · operation ID `listGrowthChains`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthChain[] | One entry per capability. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Set the order a capability tries its providers in, or go back to the default

`PUT /v1/api/growth/chains/{capability}` · operation ID `updateGrowthChain`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `capability` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateGrowthChain` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `order` | string[] | null | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthChainUpdated | The order now; it applies to the next lead pass. |
| `400` | ValidationError \| ApiError | A provider named cannot serve this capability. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin changes growth settings. |
| `404` | ApiError | No such capability. |

## Run two email finders on the same sample of the workspace's leads

`POST /v1/api/growth/chains/find_email/compare` · operation ID `compareGrowthProviders`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CompareGrowthProviders` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `providers` | —[] | **yes** |  |
| `sampleSize` | integer | no | min 1, max 25 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthProviderComparison | What each found, verified and cost. Billed like any run; nothing found is stored on the leads. |
| `400` | ValidationError \| ApiError | A provider does not find emails, or answers only in the background. |
| `401` | ApiError | No valid session or API key. |
| `402` | ApiError | The workspace is over a spend cap — its free monthly credit, its plan cap, or a limit it set itself. The body names which one and what to do about it. |
| `403` | ApiError | Only an owner or admin changes growth settings. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## List the finished delivery projects a growth brain may quote

`GET /v1/api/growth/citable-projects` · operation ID `listGrowthCitableProjects`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthCitableProject[] | Delivery projects that completed or had a deliverable approved by the client, most recently finished first. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## The size of Hlix's shared company index and how many of the workspace's companies it supplied

`GET /v1/api/growth/index` · operation ID `getGrowthIndexStats`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthIndexStats | Company counts; no workspace's identity or records are included. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Disqualify a lead or put it back in line

`PATCH /v1/api/growth/leads/{leadId}` · operation ID `updateGrowthLead`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `leadId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateGrowthLead` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `status` | `disqualified` | `new` | `queued` | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthLeadStatus | The lead's status after the change. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No lead with this id in the workspace. |
| `409` | GrowthLeadRefusal | Refused, with a `code`: `campaign_not_running` (not active, not GDPR-acknowledged, or its growth project is archived), `opted_out`, `suppressed` (address or domain on the do-not-contact list), `region_excluded` (the company is in a country the campaign excludes), `no_sendable_address` (a lookup already ran and found no verified address, so neither `new` nor `queued` can help), or `lookup_required` (`queued` on a lead never looked up: set it to `new`). |

## Answer a lead in their thread from the mailbox that wrote to them

`POST /v1/api/growth/leads/{leadId}/reply` · operation ID `sendGrowthReply`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `leadId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `SendGrowthReply` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | string | **yes** | min length 1, max length 5000 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | GrowthReplySent | Sent. |
| `202` | GrowthReplySent | Queued: it could not go this instant and the send sweep sends it. |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No lead with this id on a growth project you manage. |
| `409` | ApiError | Nothing was sent to this lead yet, or they opted out or are suppressed. |
| `502` | ApiError | The mailbox refused the email. |
| `503` | ApiError | Mailbox sending is not set up on this deployment. |

## Show a lead's whole email thread, drafts included

`GET /v1/api/growth/leads/{leadId}/thread` · operation ID `getGrowthThread`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `leadId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthThread | The lead and every email to and from them, oldest first. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No lead with this id on a growth project you manage. |

## List the workspace's sending mailboxes with their warm-up and today's sends

`GET /v1/api/growth/mailboxes` · operation ID `listGrowthMailboxes`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `includeDisconnected` | query | no | string | `true` also lists mailboxes that were disconnected; by default only the ones that can send are listed. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMailboxList | The workspace's mailboxes, oldest first. |
| `400` | ValidationError | A parameter is unknown or out of range. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Disconnect a mailbox and revoke its access

`DELETE /v1/api/growth/mailboxes/{mailboxId}` · operation ID `disconnectGrowthMailbox`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `mailboxId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMailboxDisconnected | The mailbox is disconnected; nothing more is sent from it. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin manages mailboxes. |
| `404` | ApiError | No mailbox with this id in the workspace. |
| `503` | ApiError | Mailbox sending is not set up on this deployment. |

## Change a mailbox's daily limit or warm-up start, or pause and resume it

`PATCH /v1/api/growth/mailboxes/{mailboxId}` · operation ID `updateGrowthMailbox`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `mailboxId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateGrowthMailbox` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `dailyLimit` | integer | no | min 1, max 500 |
| `rampStartedAt` | string (date-time) | no |  |
| `status` | `active` | `paused` | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMailbox | The mailbox after the change. |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin manages mailboxes. |
| `404` | ApiError | No mailbox with this id in the workspace. |
| `409` | ApiError | The mailbox lost its connection: connect it again instead of resuming it. |

## Check the mailbox domain's SPF, DKIM and DMARC records

`GET /v1/api/growth/mailboxes/{mailboxId}/dns` · operation ID `checkGrowthMailboxDns`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `mailboxId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMailboxDns | What public DNS says about the domain right now. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No mailbox with this id in the workspace. |

## Start connecting a Google or Microsoft mailbox to send from

`POST /v1/api/growth/mailboxes/connect` · operation ID `connectGrowthMailbox`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `ConnectGrowthMailbox` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `loginHint` | string (email) | no | max length 320 |
| `service` | `google` | `microsoft` | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMailboxConnect | The sign-in address. After signing in the person returns to Growth settings with the new mailbox warming up. |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin manages mailboxes. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |
| `503` | ApiError | Mailbox sending is not set up on this deployment. |

## Sort a reply by hand

`PATCH /v1/api/growth/messages/{messageId}` · operation ID `classifyGrowthMessage`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `messageId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `ClassifyGrowthMessage` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `classification` | `interested` | `later` | `no` | `unsubscribe` | `out_of_office` | `other` | null | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthClassification | The reply's sort. Interested opens a deal; unsubscribe suppresses the address at once. |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No email with this id on a growth project you manage. |
| `409` | ApiError | Only a reply can be sorted. |

## Approve a drafted email, optionally edited, so it sends

`POST /v1/api/growth/messages/{messageId}/approve` · operation ID `approveGrowthMessage`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `messageId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `ApproveGrowthMessage` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | string | no | min length 1, max length 5000 |
| `subject` | string | no | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMessage | The email, now scheduled. A first email or an answer goes at the next send inside the recipient's working day; a follow-up waits for its day. |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No email with this id on a growth project you manage. |
| `409` | ApiError | It is not a draft waiting for approval any more. |

## Record whether an email whose delivery was unknown went out

`POST /v1/api/growth/messages/{messageId}/resolve` · operation ID `resolveGrowthMessage`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `messageId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `ResolveGrowthMessage` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `sent` | boolean | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthMessageResolved | The email's status now: sent (its follow-ups get their days) or failed (its sequence stops, and a first email takes the lead out of line). |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No email with this id on a growth project you manage. |
| `409` | ApiError | The email's delivery is not unknown: it was sent, failed, or is still being sent. |

## Edit or launch a campaign

`PATCH /v1/api/growth/plays/{playId}` · operation ID `updateGrowthPlay`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `playId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateGrowthPlay` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `angle` | string | no | min length 1, max length 600 |
| `autoSendReplies` | boolean | no |  |
| `dailyBudgetMicros` | integer | no | min 0, max 1000000000 |
| `excludeDe` | boolean | no |  |
| `excludeEu` | boolean | no |  |
| `firstEmail` | object | no |  |
| `gdprAcknowledged` | boolean | no |  |
| `name` | string | no | min length 1, max length 120 |
| `reviewFirstN` | integer | no | min 0, max 1000 |
| `status` | `draft` | `active` | `paused` | `stopped` | no |  |
| `who` | object | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthPlay | The campaign after the edit. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only a person can acknowledge GDPR for a campaign. |
| `404` | ApiError | No campaign with this id in the workspace. |
| `409` | ApiError | The campaign cannot be active before GDPR is acknowledged, or while its project is archived. |

## Create a growth project from a website and start its research run

`POST /v1/api/growth/projects` · operation ID `createGrowthProject`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CreateGrowthProject` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `buyerDescription` | string | no | min length 1, max length 2000 |
| `citeProjectIds` | string[] | no |  |
| `clientAccountId` | string | no | min length 1 |
| `excludeDe` | boolean | no |  |
| `excludeEu` | boolean | no |  |
| `name` | string | no | min length 1, max length 200 |
| `website` | string | no | max length 2048 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | GrowthProjectCreated | The project and its first run, already running in the background. Progress streams on the project's observe feed. |
| `400` | ValidationError \| ApiError | The website is not a public address, or a cited project is not a finished delivery project of this workspace (see `GET /v1/api/growth/citable-projects`). |
| `401` | ApiError | No valid session or API key. |
| `402` | ApiError | The free plan already holds its maximum number of active projects, or the workspace is over a spend cap. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The client account does not exist in this workspace. |

## Show a growth project's brain, campaigns and last run

`GET /v1/api/growth/projects/{projectId}` · operation ID `getGrowthProject`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthState | The growth project's current state. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |

## Replace the Company brain

`PUT /v1/api/growth/projects/{projectId}/brain` · operation ID `updateGrowthBrain`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `GrowthBrain` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `competitors` | object[] | **yes** |  |
| `languages` | object[] | **yes** |  |
| `neverSay` | string[] | **yes** |  |
| `offer` | object | null | **yes** |  |
| `pricing` | object | null | **yes** |  |
| `proof` | object[] | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthBrainRow | The stored brain. Every source must be a web address or a delivered project. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |

## List a growth project's email threads, one per lead

`GET /v1/api/growth/projects/{projectId}/inbox` · operation ID `listGrowthInbox`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `filter` | query | no | string | needs_reply (they wrote and nobody answered), replied, sent (no reply yet), review (emails waiting for approval) or unknown (emails whose delivery a person has to confirm). |
| `limit` | query | no | string | Page size, 1–100; default 50. |
| `offset` | query | no | string | How many threads to skip; default 0. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthInboxPage | One page of threads, newest activity first. |
| `400` | ValidationError | A filter is out of range or unknown. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |

## Upload a lead list to a growth project

`POST /v1/api/growth/projects/{projectId}/lead-lists` · operation ID `uploadGrowthLeadList`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UploadGrowthLeadList` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `csv` | string | **yes** | min length 1, max length 2000000 |
| `fileName` | string | **yes** | min length 1, max length 255 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | GrowthLeadListResult | The people the list named, matched to the workspace's companies and people. Nobody is written to because of the upload: each campaign scores the listed companies and checks a listed address before it is used. Rows on the do-not-contact list, people who opted out, and companies in a country the project excludes are left out. |
| `400` | ValidationError \| ApiError | The file has no data rows, more than 5,000 rows, or no row names a person at a company. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |
| `409` | ApiError | The project is archived. |
| `413` | ApiError | The file is larger than 2 MB. |

## List a growth project's leads with their evidence and provenance

`GET /v1/api/growth/projects/{projectId}/leads` · operation ID `listGrowthLeads`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `playId` | query | no | string | Only this campaign's leads. |
| `status` | query | no | string | Only leads in this status: new, queued, contacted, replied, converted, disqualified or opted_out. |
| `minFit` | query | no | string | Only leads whose fit score (0–100) is at least this. |
| `limit` | query | no | string | Page size, 1–200; default 50. |
| `offset` | query | no | string | How many leads to skip; default 0. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthLeadPage | One page of leads, best fit first. A lead's email is looked up only when it is among the best leads the workspace can send to that day. |
| `400` | ValidationError | A filter is out of range or unknown. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |

## Run the website research again

`POST /v1/api/growth/projects/{projectId}/runs` · operation ID `rerunGrowthProject`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `RerunGrowth` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `buyerDescription` | string | null | no |  |
| `citeProjectIds` | string[] | no |  |
| `excludeDe` | boolean | no |  |
| `excludeEu` | boolean | no |  |
| `website` | string | no | max length 2048 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `202` | GrowthRun | The new run, running in the background. On success its three campaigns replace the earlier drafts. |
| `400` | ValidationError \| ApiError | The website is not a public address, or a cited project is not a finished delivery project of this workspace. |
| `401` | ApiError | No valid session or API key. |
| `402` | ApiError | The workspace is over a spend cap — its free monthly credit, its plan cap, or a limit it set itself. The body names which one and what to do about it. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |
| `409` | ApiError | A run is already in progress, the project is archived, or it has no website yet. |

## Show each campaign's data-provider spend for today and the last 30 days

`GET /v1/api/growth/projects/{projectId}/spend` · operation ID `getGrowthSpend`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthPlaySpend[] | One row per campaign of the project, oldest first. Days are UTC; the last 30 days include today. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No growth project with this id in the workspace. |

## List growth data providers and the workspace's key state

`GET /v1/api/growth/providers` · operation ID `listGrowthProviders`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthProvider[] | Every growth data provider. Stored keys are represented only by `hasApiKey`. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Turn a growth provider on or off for the workspace, or change its settings

`PATCH /v1/api/growth/providers/{provider}` · operation ID `updateGrowthProvider`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `provider` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateGrowthProvider` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `enabled` | boolean | no |  |
| `metadata` | object | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthProvider | The provider state after the change. Off means off on Hlix's key too. |
| `400` | ValidationError \| ApiError | The provider takes no workspace key, or a setting it does not declare was sent. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Remove the workspace's own key for a growth provider

`DELETE /v1/api/growth/providers/{provider}/key` · operation ID `removeGrowthProviderKey`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `provider` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthProvider | The provider state after the key was removed. |
| `400` | ValidationError \| ApiError | The provider takes no workspace key, or a setting it does not declare was sent. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Add or replace the workspace's own key for a growth provider

`PUT /v1/api/growth/providers/{provider}/key` · operation ID `saveGrowthProviderKey`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `provider` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `SaveGrowthProviderKey` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `apiKey` | string | **yes** | min length 1, max length 10000 |
| `metadata` | object | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthProvider | The provider state after saving and enabling the key. |
| `400` | ValidationError \| ApiError | The provider takes no workspace key, or a setting it does not declare was sent. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## The workspace's growth settings and this month's growth spend

`GET /v1/api/growth/settings` · operation ID `getGrowthSettings`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthSettingsState | Settings (defaults where none were set) and what this calendar month has spent against the hard cap. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Change the hard cap, the sending rules or the booking link

`PATCH /v1/api/growth/settings` · operation ID `updateGrowthSettings`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateGrowthSettings` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `bookingUrl` | string | null | no |  |
| `followUpDays` | —[] | no |  |
| `mailboxDailyMax` | integer | null | no |  |
| `monthlyCapMicros` | integer | null | no |  |
| `sendDays` | integer[] | null | no |  |
| `sendEndHour` | integer | no | min 1, max 24 |
| `sendStartHour` | integer | no | min 0, max 23 |
| `stopOnReply` | boolean | no |  |
| `timeZone` | string | null | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthSettingsState | The settings now. The cap stops new lead data and new drafts once the month's spend reaches it; the rules apply from the next send. |
| `400` | ValidationError \| ApiError | A field is invalid, or the sending window would end before it starts. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin changes growth settings. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## List the do-not-contact list

`GET /v1/api/growth/suppressions` · operation ID `listGrowthSuppressions`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `query` | query | no | string | Only entries whose address or domain contains this. |
| `limit` | query | no | string | Page size, 1–200; default 50. |
| `offset` | query | no | string | How many entries to skip; default 0. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthSuppressionPage | One page, newest first. |
| `400` | ValidationError | The body or a parameter is invalid. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Add addresses and domains to the do-not-contact list

`POST /v1/api/growth/suppressions` · operation ID `addGrowthSuppressions`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `AddGrowthSuppressions` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `entries` | string[] | **yes** |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | GrowthSuppressionsAdded | Added. Leads they reach leave the send line and their unsent emails are canceled. |
| `400` | ValidationError \| ApiError | No line was an email address or a domain. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin changes growth settings. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |

## Remove an entry a person added to the do-not-contact list

`DELETE /v1/api/growth/suppressions/{suppressionId}` · operation ID `removeGrowthSuppression`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `suppressionId` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | GrowthSuppressionRemoved | Removed. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only an owner or admin changes growth settings. |
| `404` | ApiError | No such entry in the workspace. |
| `409` | ApiError | The entry is an unsubscribe, a complaint or a bounce, which cannot be removed. |

## If a request fails

These apply to every operation on this page.

- `400` — the body failed schema validation, or the request named no active organization. A `ValidationError` body carries the failing fields; an `ApiError` body carries only `error`.
- `401` — no valid session or API key.
- `403` — authenticated, but not a member of the named organization, or a client collaborator without the required access.
- `404` — no such resource **in this workspace**. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
- `409` — the expected revision or state is stale, or another operation currently owns the transition.
- `500` — the operation failed server-side. Retry only where an idempotency key makes that safe.

## Next steps

[API reference](/api/reference/)
  [API & OpenAPI](/api/openapi/)
  [TypeScript SDK](/sdk/typescript/)
  [CLI reference](/reference/cli/)