# Create subscribers

URL: https://docs.hanzo.ai/docs/openapi/marketing/post-marketing-lists-by-id-subscribers

> Adds an address to one of the org's lists, or updates it when it is already there, and answers 201 or 200 with the row.

`POST /v1/marketing/lists/{id}/subscribers`

> [Marketing →](https://docs.hanzo.ai/docs/openapi/marketing) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                                            |
| ------------- | ---------------------------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/marketing/lists/{id}/subscribers` |
| **Method**    | `POST`                                                     |
| **Operation** | `post_marketing_lists_by_id_subscribers`                   |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`                     |

Adds an address to one of the org's lists, or updates it when it
is already there, and answers 201 or 200 with the row. Pending mails the
address a link to confirm. An address that unsubscribed or complained cannot be
put back by the org: it is 409, and the person rejoins by subscribing and
confirming again.

Org admin only.

## Request

13 fields, body `application/json` (required).

| Field       | In   | Type            | Required | Description                                                                                                                         |
| ----------- | ---- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `id`        | path | string          | yes      | ID is the list, by id or slug, from the path.                                                                                       |
| `basis`     | body | string          | —        | Basis is the consent basis to record: explicit, legitimate\_interest or unverified (the default).                                   |
| `consentAt` | body | integer (int64) | —        | ConsentAt is when consent was given, unix seconds, when it was given before this call; on add only.                                 |
| `email`     | body | string          | —        | Email is the address to add.                                                                                                        |
| `fields`    | body | object          | —        | Fields set custom field values by key; an empty value clears one.                                                                   |
| `fields.*`  | body | string          | —        |                                                                                                                                     |
| `id`        | body | string          | —        | ID is the list, by id or slug, from the path.                                                                                       |
| `language`  | body | string          | —        | Language is a BCP 47 tag.                                                                                                           |
| `name`      | body | string          | —        | Name is the person's name; at most 200 characters.                                                                                  |
| `ref`       | body | string          | —        | Ref is where the subscriber came from (a form id, a page); on add only.                                                             |
| `sid`       | body | integer (int64) | —        | SID is the subscriber to change, from the path; ignored on add.                                                                     |
| `status`    | body | string          | —        | Status is subscribed (the default on add), pending, which mails the address a link to confirm, or unsubscribed, bounced or cleaned. |
| `tags`      | body | string\[]       | —        | Tags replace the subscriber's tags.                                                                                                 |

## Response

| Status    | Body            | Meaning |
| --------- | --------------- | ------- |
| `200`     | marketing.Added | ok      |
| `201`     | marketing.Added | created |
| `default` | problem-details | refused |

`200` body — 31 fields.

| Field              | In   | Type              | Always | Description                                                                                                         |
| ------------------ | ---- | ----------------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| `clicks`           | body | integer (int64)   | —      | Clicks counts the clicks reported.                                                                                  |
| `confirmedAt`      | body | integer (int64)   | —      | ConfirmedAt is when the subscription was confirmed or, for one that needed no confirmation, began; 0 while pending. |
| `consent`          | body | marketing.Consent | —      |                                                                                                                     |
| `consent.at`       | body | integer (int64)   | —      | At is when it was given, unix seconds; for an import, the date the file carried when it carried one.                |
| `consent.basis`    | body | string            | —      | Basis is explicit, legitimate\_interest or unverified.                                                              |
| `consent.dnt`      | body | boolean           | —      | DNT records that the request carried Do Not Track (DNT: 1).                                                         |
| `consent.gpc`      | body | boolean           | —      | GPC records that the request carried Global Privacy Control (Sec-GPC: 1).                                           |
| `consent.ip`       | body | string            | —      | IP is the network address it was given from, when it was given here.                                                |
| `consent.language` | body | string            | —      | Language is the language it was asked in.                                                                           |
| `consent.method`   | body | string            | —      | Method is how it was given: double\_opt\_in, single\_opt\_in, import, api, preferences or commerce.                 |
| `consent.page`     | body | string            | —      | Page is the form or page it was given on.                                                                           |
| `created`          | body | boolean           | —      | Created is true when the address was not on the list before.                                                        |
| `createdAt`        | body | integer (int64)   | —      | CreatedAt is when the row was created, unix seconds.                                                                |
| `email`            | body | string            | —      | Email is the address, lower-cased and trimmed; one row per address per list.                                        |
| `fields`           | body | object            | —      | Fields are the values of the org's custom fields, by key.                                                           |
| `fields.*`         | body | string            | —      |                                                                                                                     |
| `id`               | body | integer (int64)   | —      | ID is the subscriber's id within the org.                                                                           |
| `language`         | body | string            | —      | Language is the subscriber's language, a BCP 47 tag.                                                                |
| `lastClickAt`      | body | integer (int64)   | —      | LastClickAt is the last click the email plane reported.                                                             |
| `lastOpenAt`       | body | integer (int64)   | —      | LastOpenAt is the last open the email plane reported.                                                               |
| `lastSentAt`       | body | integer (int64)   | —      | LastSentAt is the last broadcast sent to them.                                                                      |
| `list`             | body | string            | —      | List is the list's id.                                                                                              |
| `name`             | body | string            | —      | Name is the person's name, as given.                                                                                |
| `opens`            | body | integer (int64)   | —      | Opens counts the opens reported.                                                                                    |
| `person`           | body | string            | —      | Person is the CRM person the address is: the key the event stream, the CRM and Insights join on.                    |
| `ref`              | body | string            | —      | Ref is that place: a form id, a page, an import batch id.                                                           |
| `source`           | body | string            | —      | Source is the kind of place the membership came from: form, page, api, import or commerce.                          |
| `status`           | body | string            | —      | Status is pending, subscribed, unsubscribed, bounced, complained or cleaned.                                        |
| `tags`             | body | string\[]         | —      | Tags label the subscriber; each at most 64 characters.                                                              |
| `unsubscribedAt`   | body | integer (int64)   | —      | UnsubscribedAt is when the subscriber left; 0 while they have not.                                                  |
| `updatedAt`        | body | integer (int64)   | —      | UpdatedAt is the last change, unix seconds.                                                                         |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo marketing lists subscribers create <id>
```

**SDK**

**.ts**

```ts
import { Configuration, MarketingApi } from 'hanzoai';

const api = new MarketingApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postMarketingListsByIdSubscribers({ id: 'id', basis: "<basis>", consentAt: 0 });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import MarketingApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = MarketingApi(client).post_marketing_lists_by_id_subscribers(id='id', basis="<basis>", consent_at=0)
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.MarketingAPI.PostMarketingListsByIdSubscribers(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, marketing_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = marketing_api::post_marketing_lists_by_id_subscribers(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.MarketingApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new MarketingApi(client).postMarketingListsByIdSubscribers();
```

The method above is the one at the current release of the document. `hanzoai@8.5.914` (npm) and `hanzoai@8.5.914` (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. [SDKs →](https://docs.hanzo.ai/docs/sdks)

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/marketing/lists/<id>/subscribers \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "basis": "<basis>",
       "consentAt": 0
     }'
```

**MCP**

MCP reaches **marketing** through the `marketing` tool, which names its 82 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_marketing_audiences"
         }
       }
     }'
```

---

[Marketing API](https://docs.hanzo.ai/docs/openapi/marketing) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
