## File: README.md

[](https://zerodha.tech)

[](https://listmonk.app)

listmonk is a standalone, self-hosted, newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary. It uses a PostgreSQL database as its data store.

[](https://listmonk.app)

Visit [listmonk.app](https://listmonk.app) for more info. Check out the [**live demo**](https://demo.listmonk.app).

## Installation

### Docker

The latest image is available on DockerHub at [`listmonk/listmonk:latest`](https://hub.docker.com/r/listmonk/listmonk/tags?page=1&ordering=last_updated&name=latest).
Download and use the sample [docker-compose.yml](https://github.com/knadh/listmonk/blob/master/docker-compose.yml).


```shell
# Download the compose file to the current directory.
curl -LO https://github.com/knadh/listmonk/raw/master/docker-compose.yml

# Run the services in the background.
docker compose up -d
```
Visit `http://localhost:9000`

See [installation docs](https://listmonk.app/docs/installation)

__________________

### Binary
- Download the [latest release](https://github.com/knadh/listmonk/releases) and extract the listmonk binary.
- `./listmonk --new-config` to generate config.toml. Edit it.
- `./listmonk --install` to setup the Postgres DB (or `--upgrade` to upgrade an existing DB. Upgrades are idempotent and running them multiple times have no side effects).
- Run `./listmonk` and visit `http://localhost:9000`

See [installation docs](https://listmonk.app/docs/installation)
__________________


## Developers
listmonk is free and open source software licensed under AGPLv3. If you are interested in contributing, refer to the [developer setup](https://listmonk.app/docs/developer-setup). The backend is written in Go and the frontend is Vue with Buefy for UI. 


## License
listmonk is licensed under the AGPL v3 license.

---

## File: dev/README.md

# Docker suite for development

**NOTE**: This exists only for local development. If you're interested in using
Docker for a production setup, visit the
[docs](https://listmonk.app/docs/installation/#docker) instead.

### Objective

The purpose of this Docker suite for local development is to isolate all the dev
dependencies in a Docker environment. The containers have a host volume mounted
inside for the entire app directory. This helps us to not do a full
`docker build` for every single local change, only restarting the Docker
environment is enough.

## Setting up a dev suite

To spin up a local suite of:

- PostgreSQL
- Mailhog
- Node.js frontend app
- Golang backend app

### Verify your config file

The config file provided at `dev/config.toml` will be used when running the
containerized development stack. Make sure the values set within are suitable
for the feature you're trying to develop.

### Setup DB

Running this will build the appropriate images and initialize the database.

```bash
make init-dev-docker
```

### Start frontend and backend apps

Running this start your local development stack.

```bash
make dev-docker
```

Visit `http://localhost:8080` on your browser.

### Tear down

This will tear down all the data, including DB.

```bash
make rm-dev-docker
```

### See local changes in action

- Backend: Anytime you do a change to the Go app, it needs to be compiled. Just
  run `make dev-docker` again and that should automatically handle it for you.
- Frontend: Anytime you change the frontend code, you don't need to do anything.
  Since `yarn` is watching for all the changes and we have mounted the code
  inside the docker container, `yarn` server automatically restarts.

---

## File: docs/docs/content/apis/apis.md

# APIs

All features that are available on the listmonk dashboard are also available as REST-like HTTP APIs that can be interacted with directly. Request and response bodies are JSON. This allows easy scripting of listmonk and integration with other systems, for instance, synchronisation with external subscriber databases.

!!! note
    If you come across API calls that are yet to be documented, please consider contributing to docs.


## Auth
HTTP API requests support BasicAuth and a Authorization `token` headers. API users and tokens with the required permissions can be created and managed on the admin UI (Admin -> Users).

##### BasicAuth example
```shell
curl -u "api_user:token" http://localhost:9000/api/lists
```

##### Authorization token example
```shell
curl -H "Authorization: token api_user:token" http://localhost:9000/api/lists
```

## Permissions
**User role**: Permissions allowed for a user are defined as a *User role* (Admin -> User roles) and then attached to a user. 

**List role**: Read / write permissions per-list can be defined as a *List role* (Admin -> User roles) and then attached to a user. 

In a *User role*, `lists:get_all` or `lists:manage_all` permission supercede and override any list specific permissions for a user defined in a *List role*.

To manage lists and subscriber list subscriptions via API requests, ensure that the appropriate permissions are attached to the API user.

______________________________________________________________________

## Response structure

### Successful request

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
    "data": {}
}
```

All responses from the API server are JSON with the content-type application/json unless explicitly stated otherwise. A successful 200 OK response always has a JSON response body with a status key with the value success. The data key contains the full response payload.

### Failed request

```http
HTTP/1.1 500 Server error
Content-Type: application/json

{
    "message": "Error message"
}
```

A failure response is preceded by the corresponding 40x or 50x HTTP header. There may be an optional `data` key with additional payload.

### Timestamps

All timestamp fields are in the format `2019-01-01T09:00:00.000000+05:30`. The seconds component is suffixed by the milliseconds, followed by the `+` and the timezone offset.

### Common HTTP error codes

| Code  |                                                                             |
| ----- | ----------------------------------------------------------------------------|
|  400  | Missing or bad request parameters or values                                 |
|  403  | Session expired or invalidate. Must relogin                                 |
|  404  | Request resource was not found                                              |
|  405  | Request method (GET, POST etc.) is not allowed on the requested endpoint    |
|  410  | The requested resource is gone permanently                                  |
|  422  | Unprocessable entity. Unable to process request as it contains invalid data |
|  429  | Too many requests to the API (rate limiting)                                |
|  500  | Something unexpected went wrong                                             |
|  502  | The backend OMS is down and the API is unable to communicate with it        |
|  503  | Service unavailable; the API is down                                        |
|  504  | Gateway timeout; the API is unreachable                                     |


## OpenAPI (Swagger) spec

The auto-generated OpenAPI (Swagger) specification site for the APIs are available at [**listmonk.app/docs/swagger**](https://listmonk.app/docs/swagger/)

---

## File: docs/docs/content/apis/bounces.md

# API / Bounces

Method   | Endpoint                                                | Description
---------|---------------------------------------------------------|------------------------------------------------
GET      | [/api/bounces](#get-apibounces)                         | Retrieve bounce records.
DELETE   | [/api/bounces](#delete-apibounces)                      | Delete all/multiple bounce records.
DELETE   | [/api/bounces/{bounce_id}](#delete-apibouncesbounce_id) | Delete specific bounce record.


______________________________________________________________________

#### GET /api/bounces

Retrieve the bounce records.

##### Parameters

| Name       | Type     | Required | Description                                                      |
|:-----------|:---------|:---------|:-----------------------------------------------------------------|
| campaign_id| number   |          | Bounce record retrieval for particular campaign id               |
| page       | number   |          | Page number for pagination.                                      |
| per_page   | number   |          | Results per page. Set to 'all' to return all results.            |
| source     | string   |          |                                |
| order_by   | string   |          | Fields by which bounce records are ordered. Options:"email", "campaign_name", "source", "created_at".        |
| order      | number   |          | Sorts the result. Allowed values: 'asc','desc'                   |

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/bounces?campaign_id=1&page=1&per_page=2' \ 
    -H 'accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' \
    --data '{"source":"demo","order_by":"created_at","order":"asc"}'
```

##### Example Response

```json
{
  "data": {
    "results": [
      {
        "id": 839971,
        "type": "hard",
        "source": "demo",
        "meta": {
          "some": "parameter"
        },
        "created_at": "2024-08-20T23:54:22.851858Z",
        "email": "gilles.deleuze@example.app",
        "subscriber_uuid": "32ca1f3e-1a1d-42e1-af04-df0757f420f3",
        "subscriber_id": 60,
        "campaign": {
          "id": 1,
          "name": "Test campaign"
        }
      },
      {
        "id": 839725,
        "type": "hard",
        "source": "demo",
        "meta": {
          "some": "parameter"
        },
        "created_at": "2024-08-20T22:46:36.393547Z",
        "email": "gottfried.leibniz@example.app",
        "subscriber_uuid": "5911d3f4-2346-4bfc-aad2-eb319ab0e879",
        "subscriber_id": 13,
        "campaign": {
          "id": 1,
          "name": "Test campaign"
        }
      }
    ],
    "query": "",
    "total": 528,
    "per_page": 2,
    "page": 1
  }
}
```

______________________________________________________________________

#### DELETE /api/bounces

To delete all bounces.

##### Parameters

| Name    | Type      | Required | Description                          |
|:--------|:----------|:---------|:-------------------------------------|
| all     | bool      | Yes      | Bool to confirm deleting all bounces |

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/bounces?all=true'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/bounces

To delete multiple bounce records.

##### Parameters

| Name    | Type      | Required | Description                          |
|:--------|:----------|:---------|:-------------------------------------|
| id      | number    | Yes      | Id's of bounce records to delete.    |

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/bounces?id=840965&id=840168&id=840879'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/bounces/{bounce_id}

To delete specific bounce id.

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/bounces/840965'
```

##### Example Response

```json
{
    "data": true
}
```

---

## File: docs/docs/content/apis/campaigns.md

# API / Campaigns

| Method | Endpoint                                                                    | Description                               |
| :----- | :-------------------------------------------------------------------------- | :---------------------------------------- |
| GET    | [/api/campaigns](#get-apicampaigns)                                         | Retrieve all campaigns.                   |
| GET    | [/api/campaigns/{campaign_id}](#get-apicampaignscampaign_id)                | Retrieve a specific campaign.             |
| GET    | [/api/campaigns/{campaign_id}/preview](#get-apicampaignscampaign_idpreview) | Retrieve preview of a campaign.           |
| GET    | [/api/campaigns/running/stats](#get-apicampaignsrunningstats)               | Retrieve stats of specified campaigns.    |
| GET    | [/api/campaigns/analytics/{type}](#get-apicampaignsanalyticstype)           | Retrieve view counts for a  campaign.     |
| POST   | [/api/campaigns](#post-apicampaigns)                                        | Create a new campaign.                    |
| POST   | [/api/campaigns/{campaign_id}/test](#post-apicampaignscampaign_idtest)      | Test campaign with arbitrary subscribers. |
| PUT    | [/api/campaigns/{campaign_id}](#put-apicampaignscampaign_id)                | Update a campaign.                        |
| PUT    | [/api/campaigns/{campaign_id}/status](#put-apicampaignscampaign_idstatus)   | Change status of a campaign.              |
| PUT    | [/api/campaigns/{campaign_id}/archive](#put-apicampaignscampaign_idarchive) | Publish campaign to public archive.       |
| DELETE | [/api/campaigns/{campaign_id}](#delete-apicampaignscampaign_id)             | Delete a campaign.                        |
| DELETE | [/api/campaigns](#delete-apicampaigns)                                      | Delete multiple campaigns.                |

____________________________________________________________________________________________________________________________________

#### GET /api/campaigns

Retrieve all campaigns.

##### Example Request

```shell
 curl -u "api_user:token" -X GET 'http://localhost:9000/api/campaigns?page=1&per_page=100'
```

##### Parameters

| Name     | Type     | Required | Description                                                              |
| :------- | :------- | :------- | :----------------------------------------------------------------------- |
| order    | string   |          | Sorting order: ASC for ascending, DESC for descending.                   |
| order_by | string   |          | Result sorting field. Options: name, status, created_at, updated_at.     |
| query    | string   |          | String to filtter by campaign name and subject (fulltext and substring). |
| status   | []string |          | Status to filter campaigns. Repeat in the query for multiple values.     |
| tags     | []string |          | Tags to filter campaigns. Repeat in the query for multiple values.       |
| page     | number   |          | Page number for paginated results.                                       |
| per_page | number   |          | Results per page. Set as 'all' for all results.                          |
| no_body  | boolean  |          | When set to true, returns response without body content.                 |

##### Example Response

```json
{
    "data": {
        "results": [
            {
                "id": 1,
                "created_at": "2020-03-14T17:36:41.29451+01:00",
                "updated_at": "2020-03-14T17:36:41.29451+01:00",
                "views": 0,
                "clicks": 0,
                "lists": [
                    {
                        "id": 1,
                        "name": "Default list"
                    }
                ],
                "started_at": null,
                "to_send": 0,
                "sent": 0,
                "uuid": "57702beb-6fae-4355-a324-c2fd5b59a549",
                "type": "regular",
                "name": "Test campaign",
                "subject": "Welcome to listmonk",
                "from_email": "No Reply <noreply@yoursite.com>",
                "body": "<h3>Hi {{ .Subscriber.FirstName }}!</h3>\n\t\t\tThis is a test e-mail campaign. Your second name is {{ .Subscriber.LastName }} and you are from {{ .Subscriber.Attribs.city }}.",
                "body_source": null,
                "send_at": "2020-03-15T17:36:41.293233+01:00",
                "status": "draft",
                "content_type": "richtext",
                "tags": [
                    "test-campaign"
                ],
                "template_id": 1,
                "messenger": "email"
            }
        ],
        "query": "",
        "total": 1,
        "per_page": 20,
        "page": 1
    }
}
```

______________________________________________________________________

#### GET /api/campaigns/{campaign_id}

Retrieve a specific campaign.

##### Parameters

| Name        | Type    | Required | Description                                              |
| :---------- | :------ | :------- | :------------------------------------------------------- |
| campaign_id | number  | Yes      | Campaign ID.                                             |
| no_body     | boolean |          | When set to true, returns response without body content. |

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/campaigns/1'
```

##### Example Response

```json
{
    "data": {
        "id": 1,
        "created_at": "2020-03-14T17:36:41.29451+01:00",
        "updated_at": "2020-03-14T17:36:41.29451+01:00",
        "views": 0,
        "clicks": 0,
        "lists": [
            {
                "id": 1,
                "name": "Default list"
            }
        ],
        "started_at": null,
        "to_send": 0,
        "sent": 0,
        "uuid": "57702beb-6fae-4355-a324-c2fd5b59a549",
        "type": "regular",
        "name": "Test campaign",
        "subject": "Welcome to listmonk",
        "from_email": "No Reply <noreply@yoursite.com>",
        "body": "<h3>Hi {{ .Subscriber.FirstName }}!</h3>\n\t\t\tThis is a test e-mail campaign. Your second name is {{ .Subscriber.LastName }} and you are from {{ .Subscriber.Attribs.city }}.",
        "body_source": null,
        "send_at": "2020-03-15T17:36:41.293233+01:00",
        "status": "draft",
        "content_type": "richtext",
        "tags": [
            "test-campaign"
        ],
        "template_id": 1,
        "messenger": "email"
    }
}
```

______________________________________________________________________

#### GET /api/campaigns/{campaign_id}/preview

Preview a specific campaign.

##### Parameters

| Name        | Type   | Required | Description             |
| :---------- | :----- | :------- | :---------------------- |
| campaign_id | number | Yes      | Campaign ID to preview. |

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/campaigns/1/preview'
```

##### Example Response

```html
<h3>Hi John!</h3>
This is a test e-mail campaign. Your second name is Doe and you are from Bengaluru.
```

______________________________________________________________________

#### GET /api/campaigns/running/stats

Retrieve stats of specified campaigns.

##### Parameters

| Name        | Type   | Required | Description                    |
| :---------- | :----- | :------- | :----------------------------- |
| campaign_id | number | Yes      | Campaign IDs to get stats for. |

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/campaigns/running/stats?campaign_id=1'
```

##### Example Response

```json
{
    "data": []
}
```

______________________________________________________________________

#### GET /api/campaigns/analytics/{type}

Retrieve stats of specified campaigns.

##### Parameters

| Name | Type       | Required | Description                                   |
| :--- | :--------- | :------- | :-------------------------------------------- |
| id   | number\[\] | Yes      | Campaign IDs to get stats for.                |
| type | string     | Yes      | Analytics type: views, links, clicks, bounces |
| from | string     | Yes      | Start value of date range.                    |
| to   | string     | Yes      | End value of date range.                      |


##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/campaigns/analytics/views?id=1&from=2024-08-04&to=2024-08-12'
```

##### Example Response

```json
{
  "data": [
    {
      "campaign_id": 1,
      "count": 10,
      "timestamp": "2024-08-04T00:00:00Z"
    },
    {
      "campaign_id": 1,
      "count": 14,
      "timestamp": "2024-08-08T00:00:00Z"
    },
    {
      "campaign_id": 1,
      "count": 20,
      "timestamp": "2024-08-09T00:00:00Z"
    },
    {
      "campaign_id": 1,
      "count": 21,
      "timestamp": "2024-08-10T00:00:00Z"
    },
    {
      "campaign_id": 1,
      "count": 21,
      "timestamp": "2024-08-11T00:00:00Z"
    }
  ]
}
```

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/campaigns/analytics/links?id=1&from=2024-08-04T18%3A30%3A00.624Z&to=2024-08-12T18%3A29%3A00.624Z'
```

##### Example Response

```json
{
  "data": [
    {
      "url": "https://freethebears.org",
      "count": 294
    },
    {
      "url": "https://calmcode.io",
      "count": 278
    },
    {
      "url": "https://climate.nasa.gov",
      "count": 261
    },
    {
      "url": "https://www.storybreathing.com",
      "count": 260
    }
  ]
}
```

______________________________________________________________________

#### POST /api/campaigns

Create a new campaign.

##### Parameters

| Name         | Type       | Required | Description                                                                                                            |
| :----------- | :--------- | :------- | :--------------------------------------------------------------------------------------------------------------------- |
| name         | string     | Yes      | Campaign name.                                                                                                         |
| subject      | string     | Yes      | Campaign email subject.                                                                                                |
| lists        | number\[\] | Yes      | List IDs to send campaign to.                                                                                          |
| from_email   | string     |          | 'From' email in campaign emails. Defaults to value from settings if not provided.                                      |
| type         | string     | Yes      | Campaign type: 'regular' or 'optin'.                                                                                   |
| content_type | string     | Yes      | Content type: 'richtext', 'html', 'markdown', 'plain', 'visual'.                                                       |
| body         | string     | Yes      | Content body of campaign.                                                                                              |
| body_source  | string     |          | If content_type is `visual`, the JSON block source of the body.                                                        |
| altbody      | string     |          | Alternate plain text body for HTML (and richtext) emails.                                                              |
| send_at      | string     |          | Timestamp to schedule campaign. Format: 'YYYY-MM-DDTHH:MM:SSZ'.                                                        |
| messenger    | string     |          | 'email' or a custom messenger defined in settings. Defaults to 'email' if not provided.                                |
| template_id  | number     |          | Template ID to use. Defaults to default template if not provided.                                                      |
| tags         | string\[\] |          | Tags to mark campaign.                                                                                                 |
| headers      | JSON       |          | Key-value pairs to send as SMTP headers. Supports template expressions (e.g., `{{ .Subscriber.UUID }}`). Example: \[{"x-custom-header": "value"}, {"x-subscriber": "{{ .Subscriber.UUID }}"}\]. |
| attribs      | JSON       |          | Optional JSON object attributes that can be used in the campaign message template. Example `{"location": "Somewhere"}` |

##### Example request

```shell
curl -u "api_user:token" 'http://localhost:9000/api/campaigns' -X POST -H 'Content-Type: application/json;charset=utf-8' --data-raw '{"name":"Test campaign","subject":"Hello, world","lists":[1],"from_email":"listmonk <noreply@listmonk.yoursite.com>","content_type":"richtext","messenger":"email","type":"regular","tags":["test"],"template_id":1}'
```

##### Example response

```json
{
    "data": {
        "id": 1,
        "created_at": "2021-12-27T11:50:23.333485Z",
        "updated_at": "2021-12-27T11:50:23.333485Z",
        "views": 0,
        "clicks": 0,
        "bounces": 0,
        "lists": [{
            "id": 1,
            "name": "Default list"
        }],
        "started_at": null,
        "to_send": 1,
        "sent": 0,
        "uuid": "90c889cc-3728-4064-bbcb-5c1c446633b3",
        "type": "regular",
        "name": "Test campaign",
        "subject": "Hello, world",
        "from_email": "listmonk \u003cnoreply@listmonk.yoursite.com\u003e",
        "body": "",
        "body_source": null,
        "altbody": null,
        "send_at": null,
        "status": "draft",
        "content_type": "richtext",
        "tags": ["test"],
        "template_id": 1,
        "messenger": "email",
        "headers": {},
        "attribs": {}
    }
}
```

______________________________________________________________________

#### POST /api/campaigns/{campaign_id}/test

Test campaign with arbitrary subscribers.

Use the same parameters in [POST /api/campaigns](#post-apicampaigns) in addition to the below parameters.

##### Parameters

| Name        | Type       | Required | Description                                        |
| :---------- | :--------- | :------- | :------------------------------------------------- |
| subscribers | string\[\] | Yes      | List of subscriber e-mails to send the message to. |

______________________________________________________________________

#### PUT /api/campaigns/{campaign_id}

Update a campaign.

> Refer to parameters from [POST /api/campaigns](#post-apicampaigns)

______________________________________________________________________

#### PUT /api/campaigns/{campaign_id}

Update a specific campaign.

> Refer to parameters from [POST /api/campaigns](#post-apicampaigns)

______________________________________________________________________

#### PUT /api/campaigns/{campaign_id}/status

Change status of a campaign.

##### Parameters

| Name        | Type   | Required | Description                                                             |
| :---------- | :----- | :------- | :---------------------------------------------------------------------- |
| campaign_id | number | Yes      | Campaign ID to change status.                                           |
| status      | string | Yes      | New status for campaign: 'scheduled', 'running', 'paused', 'cancelled'. |

##### Note

> - Only 'scheduled' campaigns can change status to 'draft'.
> - Only 'draft' campaigns can change status to 'scheduled'.
> - Only 'paused' and 'draft' campaigns can start ('running' status).
> - Only 'running' campaigns can change status to 'cancelled' and 'paused'.

##### Example Request

```shell
curl -u "api_user:token" -X PUT 'http://localhost:9000/api/campaigns/1/status' \
--header 'Content-Type: application/json' \
--data-raw '{"status":"scheduled"}'
```

##### Example Response

```json
{
    "data": {
        "id": 1,
        "created_at": "2020-03-14T17:36:41.29451+01:00",
        "updated_at": "2020-04-08T19:35:17.331867+01:00",
        "views": 0,
        "clicks": 0,
        "lists": [
            {
                "id": 1,
                "name": "Default list"
            }
        ],
        "started_at": null,
        "to_send": 0,
        "sent": 0,
        "uuid": "57702beb-6fae-4355-a324-c2fd5b59a549",
        "type": "regular",
        "name": "Test campaign",
        "subject": "Welcome to listmonk",
        "from_email": "No Reply <noreply@yoursite.com>",
        "body": "<h3>Hi {{ .Subscriber.FirstName }}!</h3>\n\t\t\tThis is a test e-mail campaign. Your second name is {{ .Subscriber.LastName }} and you are from {{ .Subscriber.Attribs.city }}.",
        "send_at": "2020-03-15T17:36:41.293233+01:00",
        "status": "scheduled",
        "content_type": "richtext",
        "tags": [
            "test-campaign"
        ],
        "template_id": 1,
        "messenger": "email"
    }
}
```

______________________________________________________________________

#### PUT /api/campaigns/{campaign_id}/archive

Publish campaign to public archive.

##### Parameters

| Name                | Type        | Required | Description                                                               |
| :------------------ | :---------- | :------- | :------------------------------------------------------------------------ |
| campaign_id         | number      | Yes      | Campaign ID to publish to public archive.                                 |
| archive             | bool        | Yes      | State of the public archive.                                              |
| archive_template_id | number      | No       | Archive template id. Defaults to 0.                                       |
| archive_meta        | JSON string | No       | Optional Metadata to use in campaign message or template.Eg: name, email. |
| archive_slug        | string      | No       | Name for page to be used in public archive URL                            |


##### Example Request

```shell

curl -u "api_user:token" -X PUT 'http://localhost:8080/api/campaigns/33/archive' 
--header 'Content-Type: application/json' 
--data-raw '{"archive":true,"archive_template_id":1,"archive_meta":{},"archive_slug":"my-newsletter-old-edition"}'
```

##### Example Response

```json
{
  "data": {
    "archive": true,
    "archive_template_id": 1,
    "archive_meta": {},
    "archive_slug": "my-newsletter-old-edition"
  }
}
```

______________________________________________________________________

#### DELETE /api/campaigns/{campaign_id}

Delete a campaign.

##### Parameters

| Name        | Type   | Required | Description            |
| :---------- | :----- | :------- | :--------------------- |
| campaign_id | number | Yes      | Campaign ID to delete. |

##### Example Request

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/campaigns/34'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/campaigns

Delete multiple campaigns by IDs or by a search query.

##### Parameters

| Name  | Type       | Required                      | Description                                                                 |
| :---- | :--------- | :---------------------------- | :-------------------------------------------------------------------------- |
| id    | number\[\] | Yes (if `query` not provided) | Onr or more campaign IDs to delete.                                         |
| query | string     | Yes (if `id` not provided)    | Fulltext search query to filter campaigns for deletion (same as GET query). |

##### Example Request (by IDs)

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/campaigns?id=10&id=11&id=12'
```

##### Example Request (by search query)

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/campaigns?query=test%20campaign'
```

##### Example Response

```json
{
    "data": true
}
```

---

## File: docs/docs/content/apis/import.md

# API / Import

Method   | Endpoint                                        | Description
---------|-------------------------------------------------|------------------------------------------------
GET      | [/api/import/subscribers](#get-apiimportsubscribers) | Retrieve import statistics.
GET      | [/api/import/subscribers/logs](#get-apiimportsubscriberslogs) | Retrieve import logs.
POST     | [/api/import/subscribers](#post-apiimportsubscribers) | Upload a file for bulk subscriber import.
DELETE   | [/api/import/subscribers](#delete-apiimportsubscribers) | Stop and remove an import.

______________________________________________________________________

#### GET /api/import/subscribers

Retrieve the status of an ongoing import.

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/import/subscribers'
```

##### Example Response

```json
{
    "data": {
        "name": "",
        "total": 0,
        "imported": 0,
        "status": "none"
    }
}
```

______________________________________________________________________

#### GET /api/import/subscribers/logs

Retrieve logs from an ongoing import.

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/import/subscribers/logs'
```

##### Example Response

```json
{
    "data": "2020/04/08 21:55:20 processing 'import.csv'\n2020/04/08 21:55:21 imported finished\n"
}
```

______________________________________________________________________

#### POST /api/import/subscribers

Send a CSV (optionally ZIP compressed) file to import subscribers. Use a multipart form POST.

##### Parameters

| Name   | Type        | Required | Description                              |
|:-------|:------------|:---------|:-----------------------------------------|
| params | JSON string | Yes      | Stringified JSON with import parameters. |
| file   | file        | Yes      | File for upload.                         |


#### `params` (JSON string)
| Name      | Type     | Required | Description                                                                                                                        |
|:----------|:---------|:---------|:-----------------------------------------------------------------------------------------------------------------------------------|
| mode      | string   | Yes      | `subscribe` or `blocklist`                                                                                                         |
| delim     | string   | Yes      | Single character indicating delimiter used in the CSV file, eg: `,`                                                                |
| lists     | []number |          | Array of list IDs to subscribe to.                                                                                                 |
| overwrite | bool     |          | Whether to overwrite the subscriber parameters including subscriptions or ignore records that are already present in the database. |

##### Example Request

```shell
curl -u "api_user:token" -X POST 'http://localhost:9000/api/import/subscribers' \
  -F 'params={"mode":"subscribe", "subscription_status":"confirmed", "delim":",", "lists":[1, 2], "overwrite": true}' \
  -F "file=@/path/to/subs.csv"
```

##### Example Response

```json
    {
        "mode": "subscribe", // subscribe or blocklist
        "delim": ",",        // delimiter in the uploaded file
        "lists":[1],         // array of list IDs to import into
        "overwrite": true    // overwrite existing entries or skip them?
    }
```

______________________________________________________________________

#### DELETE /api/import/subscribers

Stop and delete an ongoing import.

##### Example Request

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/import/subscribers' 
```

##### Example Response

```json
{
    "data": {
        "name": "",
        "total": 0,
        "imported": 0,
        "status": "none"
    }
}
```

---

## File: docs/docs/content/apis/lists.md

# API / Lists

| Method | Endpoint                                        | Description               |
| :----- | :---------------------------------------------- | :------------------------ |
| GET    | [/api/lists](#get-apilists)                     | Retrieve all lists.       |
| GET    | [/api/public/lists](#get-public-apilists)       | Retrieve public lists.    |
| GET    | [/api/lists/{list_id}](#get-apilistslist_id)    | Retrieve a specific list. |
| POST   | [/api/lists](#post-apilists)                    | Create a new list.        |
| PUT    | [/api/lists/{list_id}](#put-apilistslist_id)    | Update a list.            |
| DELETE | [/api/lists/{list_id}](#delete-apilistslist_id) | Delete a list.            |
| DELETE | [/api/lists](#delete-apilists)                  | Delete multiple lists.    |

______________________________________________________________________

#### GET /api/lists

Retrieve lists.

> **Note:** Lists with `status: archived` are hidden from list selectors in campaigns, public subscription forms, and roles by default. They can only be viewed by filtering with `status=archived` or by viewing all lists without a status filter.

##### Parameters

| Name     | Type     | Required | Description                                                                                        |
| :------- | :------- | :------- | :------------------------------------------------------------------------------------------------- |
| query    | string   |          | String for list name search.                                                                       |
| status   | string   |          | Status to filter lists. Options: active, archived. Defaults to showing all lists if not specified. |
| minimal  | boolean  |          | If true, returns lists without subscriber counts (faster). Defaults to false.                      |
| tag      | []string |          | Tags to filter lists. Repeat in the query for multiple values.                                     |
| order_by | string   |          | Sort field. Options: name, status, created_at, updated_at.                                         |
| order    | string   |          | Sorting order. Options: ASC, DESC.                                                                 |
| page     | number   |          | Page number for pagination.                                                                        |
| per_page | number   |          | Results per page. Set to 'all' to return all results.                                              |

##### Example Request

```shell
# Get all lists
curl -u "api_user:token" -X GET 'http://localhost:9000/api/lists?page=1&per_page=100'

# Get only active lists
curl -u "api_user:token" -X GET 'http://localhost:9000/api/lists?status=active&per_page=100'

# Get archived lists with minimal data
curl -u "api_user:token" -X GET 'http://localhost:9000/api/lists?status=archived&minimal=true&per_page=all'
```

##### Example Response

```json
{
    "data": {
        "results": [
            {
                "id": 1,
                "created_at": "2020-02-10T23:07:16.194843+01:00",
                "updated_at": "2020-03-06T22:32:01.118327+01:00",
                "uuid": "ce13e971-c2ed-4069-bd0c-240e9a9f56f9",
                "name": "Default list",
                "type": "public",
                "optin": "double",
                "status": "active",
                "tags": [
                    "test"
                ],
                "subscriber_count": 2
            },
            {
                "id": 2,
                "created_at": "2020-03-04T21:12:09.555013+01:00",
                "updated_at": "2020-03-06T22:34:46.405031+01:00",
                "uuid": "f20a2308-dfb5-4420-a56d-ecf0618a102d",
                "name": "get",
                "type": "private",
                "optin": "single",
                "status": "active",
                "tags": [],
                "subscriber_count": 0
            }
        ],
        "total": 5,
        "per_page": 20,
        "page": 1
    }
}
```

______________________________________________________________________

#### GET /api/public/lists

Retrieve public lists with name and uuid to submit a subscription. This is an unauthenticated call to enable scripting to subscription form.

> **Note:** This endpoint only returns lists with `type: public` and `status: active`. Archived lists are never shown on public subscription forms.

##### Example Request

```shell
curl -X GET 'http://localhost:9000/api/public/lists'
```

##### Example Response

```json
[
  {
    "uuid": "55e243af-80c6-4169-8d7f-bc571e0269e9",
    "name": "Opt-in list"
  }
]
```
______________________________________________________________________

#### GET /api/lists/{list_id}

Retrieve a specific list.

##### Parameters

| Name    | Type   | Required | Description                 |
| :------ | :----- | :------- | :-------------------------- |
| list_id | number | Yes      | ID of the list to retrieve. |

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/lists/5'
```

##### Example Response

```json
{
    "data": {
        "id": 5,
        "created_at": "2020-03-07T06:31:06.072483+01:00",
        "updated_at": "2020-03-07T06:31:06.072483+01:00",
        "uuid": "1bb246ab-7417-4cef-bddc-8fc8fc941d3a",
        "name": "Test list",
        "type": "public",
        "optin": "double",
        "status": "active",
        "tags": [],
        "subscriber_count": 0
    }
}
```

______________________________________________________________________

#### POST /api/lists

Create a new list.

##### Parameters

| Name        | Type       | Required | Description                                                        |
| :---------- | :--------- | :------- | :----------------------------------------------------------------- |
| name        | string     | Yes      | Name of the new list.                                              |
| type        | string     | Yes      | Type of list. Options: private, public.                            |
| optin       | string     | Yes      | Opt-in type. Options: single, double.                              |
| status      | string     | No       | Status of the list. Options: active, archived. Defaults to active. |
| tags        | string\[\] |          | Associated tags for a list.                                        |
| description | string     | No       | Description of the new list.                                       |

##### Example Request

```shell
curl -u "api_user:token" -X POST 'http://localhost:9000/api/lists'
```

##### Example Response

```json
{
    "data": {
        "id": 5,
        "created_at": "2020-03-07T06:31:06.072483+01:00",
        "updated_at": "2020-03-07T06:31:06.072483+01:00",
        "uuid": "1bb246ab-7417-4cef-bddc-8fc8fc941d3a",
        "name": "Test list",
        "type": "public",
        "optin": "single",
        "status": "active",
        "tags": [],
        "subscriber_count": 0,
        "description": "This is a test list"
    }
}
```

______________________________________________________________________

#### PUT /api/lists/{list_id}

Update a list.

##### Parameters

| Name        | Type       | Required | Description                                    |
| :---------- | :--------- | :------- | :--------------------------------------------- |
| list_id     | number     | Yes      | ID of the list to update.                      |
| name        | string     |          | New name for the list.                         |
| type        | string     |          | Type of list. Options: private, public.        |
| optin       | string     |          | Opt-in type. Options: single, double.          |
| status      | string     |          | Status of the list. Options: active, archived. |
| tags        | string\[\] |          | Associated tags for the list.                  |
| description | string     |          | Description of the list.                       |

##### Example Request

```shell
curl -u "api_user:token" -X PUT 'http://localhost:9000/api/lists/5' \
--form 'name=modified test list' \
--form 'type=private'
```

##### Example Response

```json
{
    "data": {
        "id": 5,
        "created_at": "2020-03-07T06:31:06.072483+01:00",
        "updated_at": "2020-03-07T06:52:15.208075+01:00",
        "uuid": "1bb246ab-7417-4cef-bddc-8fc8fc941d3a",
        "name": "modified test list",
        "type": "private",
        "optin": "single",
        "status": "active",
        "tags": [],
        "subscriber_count": 0,
        "description": "This is a test list"
    }
}
```

______________________________________________________________________

#### DELETE /api/lists/{list_id}

Delete a specific list.

##### Parameters

| Name    | Type   | Required | Description               |
| :------ | :----- | :------- | :------------------------ |
| list_id | Number | Yes      | ID of the list to delete. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/lists/1'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/lists

Delete multiple lists by IDs or by a search query.

> **Note:** Users can only delete lists they have `manage` permission for. Any lists in the query that the user doesn't have permission to manage is ignored.

##### Parameters

| Name  | Type       | Required                      | Description                                                        |
| :---- | :--------- | :---------------------------- | :----------------------------------------------------------------- |
| id    | number\[\] | Yes (if `query` not provided) | One or more list IDs to delete.                                    |
| query | string     | Yes (if `id` not provided)    | Search query to filter lists for deletion (same as the GET query). |

##### Example Request (by IDs)

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/lists?id=10&id=11&id=12'
```

##### Example Request (by search query)

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/lists?query=test%20list'
```

##### Example Response

```json
{
    "data": true
}
```

---

## File: docs/docs/content/apis/media.md

# API / Media

Method | Endpoint                                             | Description
-------|------------------------------------------------------|---------------------------------
GET    | [/api/media](#get-apimedia)                          | Get uploaded media file
GET    | [/api/media/{media_id}](#get-apimediamedia_id)       | Get specific uploaded media file
POST   | [/api/media](#post-apimedia)                         | Upload media file
DELETE | [/api/media/{media_id}](#delete-apimediamedia_id)    | Delete uploaded media file

______________________________________________________________________

#### GET /api/media

Get an uploaded media file.

##### Example Request

```shell
curl -u "api_user:token" -X GET 'http://localhost:9000/api/media' \
--header 'Content-Type: multipart/form-data; boundary=--------------------------093715978792575906250298'
```

##### Example Response

```json
{
    "data": [
        {
            "id": 1,
            "uuid": "ec7b45ce-1408-4e5c-924e-965326a20287",
            "filename": "Media file",
            "created_at": "2020-04-08T22:43:45.080058+01:00",
            "thumb_url": "/uploads/image_thumb.jpg",
            "uri": "/uploads/image.jpg"
        }
    ]
}
```
______________________________________________________________________

#### GET /api/media/{media_id}

Retrieve a specific media.

##### Parameters

| Name          | Type      | Required | Description      |
|:--------------|:----------|:---------|:-----------------|
| media_id      | Number    | Yes      | Media ID.        |

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/media/7' 
```

##### Example Response

```json
{
  "data": 
    {
        "id": 7,
        "uuid": "62e32e97-d6ca-4441-923f-b62607000dd1",
        "filename": "ResumeB.pdf",
        "content_type": "application/pdf",
        "created_at": "2024-08-06T11:28:53.888257+05:30",
        "thumb_url": null,
        "provider": "filesystem",
        "meta": {},
        "url": "http://localhost:9000/uploads/ResumeB.pdf"
    }
}
```
______________________________________________________________________

#### POST /api/media

Upload a media file.

##### Parameters

| Field | Type      | Required | Description         |
|-------|-----------|----------|---------------------|
| file  | File      | Yes      | Media file to upload|

##### Example Request

```shell
curl -u "api_user:token" -X POST 'http://localhost:9000/api/media' \
--header 'Content-Type: multipart/form-data; boundary=--------------------------183679989870526937212428' \
--form 'file=@/path/to/image.jpg'
```

##### Example Response

```json
{
    "data": {
        "id": 1,
        "uuid": "ec7b45ce-1408-4e5c-924e-965326a20287",
        "filename": "Media file",
        "created_at": "2020-04-08T22:43:45.080058+01:00",
        "thumb_uri": "/uploads/image_thumb.jpg",
        "uri": "/uploads/image.jpg"
    }
}
```

______________________________________________________________________

#### DELETE /api/media/{media_id}

Delete an uploaded media file.

##### Parameters

| Field    | Type      | Required | Description             |
|----------|-----------|----------|-------------------------|
| media_id | number    | Yes      | ID of media file to delete |

##### Example Request

```shell
curl -u "api_user:token" -X DELETE 'http://localhost:9000/api/media/1'
```

##### Example Response

```json
{
    "data": true
}
```

---

## File: docs/docs/content/apis/sdks.md

# SDKs and client libraries

A list of 3rd party client libraries and SDKs that have been written for listmonk APIs.

!!! note
	The list is community sourced. They have not been verified and are not officially supported.

- [WordPress - WooCommerce plugin](https://github.com/post-duif/integration-listmonk-wordpress-plugin) integration for listmonk
- [listmonk ](https://github.com/mikeckennedy/listmonk) — Python API client
- [listmonk-api](https://github.com/Knuckles-Team/listmonk-api) — Python API client
- [frappe_listmonk](https://github.com/anandology/frappe_listmonk) — Frappe framework integration for listmonk
- [auto-newsletter-listmonk](https://github.com/chaddyc/auto-newsletter-listmonk) — Ghost CMS integration
- [listmonk-newsletter](https://github.com/iloveitaly/listmonk-newsletter) - RSS to listmonk integration for email newsletters
- [listmonk-crysctal](https://github.com/russ/listmonk-crystal) — Crystal lang API client
- [terraform-provider-listmonk](https://github.com/Muravlev/terraform-provider-listmonk) — Manage listmonk templates in Terraform
- [listmonk-php-client](https://github.com/arunnabraham/listmonk-php-client) — PHP API client
- [php-listmonk](https://github.com/junisan/php-listmonk) — PHP API client
- [go-listmonk](https://github.com/EzeXchange-API/go-listmonk) — Go API client
- [listmonk-ruby](https://github.com/polydice/listmonk-ruby) — Ruby API client
- [listmonk-nodejs-api](https://github.com/mihairaulea/listmonk-nodejs-api) — NodeJS API client
- [@maloma/listmonk](https://codeberg.org/maloma/listmonk-sdk) — NodeJS/Bun Typescript SDK
- [listmonk-laravel](https://github.com/theafolayan/listmonk-laravel) — Laravel API Client
- [nuxt-listmonk](https://github.com/roncallyt/nuxt-listmonk) — Listmonk module for Nuxt.js
- [listmonk-japi](https://codeberg.org/hlassiege/listmonk-japi) - Listmonk client for Java/kotlin
- [listmonk-mcp](https://github.com/rhnvrm/listmonk-mcp) — MCP (Model Context Protocol) server for Claude integration
- [N8N Nodes](https://github.com/wiesinghilker/n8n-nodes-listmonk) — Adds Listmonk Nodes for N8N Automations

---

## File: docs/docs/content/apis/subscribers.md

# API / Subscribers

| Method | Endpoint                                                                                | Description                                    |
| ------ | --------------------------------------------------------------------------------------- | ---------------------------------------------- |
| GET    | [/api/subscribers](#get-apisubscribers)                                                 | Query and retrieve subscribers.                |
| GET    | [/api/subscribers/{subscriber_id}](#get-apisubscriberssubscriber_id)                    | Retrieve a specific subscriber.                |
| GET    | [/api/subscribers/{subscriber_id}/export](#get-apisubscriberssubscriber_idexport)       | Export a specific subscriber.                  |
| GET    | [/api/subscribers/{subscriber_id}/bounces](#get-apisubscriberssubscriber_idbounces)     | Retrieve a  subscriber bounce records.         |
| POST   | [/api/subscribers](#post-apisubscribers)                                                | Create a new subscriber.                       |
| POST   | [/api/subscribers/{subscriber_id}/optin](#post-apisubscriberssubscriber_idoptin)        | Sends optin confirmation email to subscribers. |
| POST   | [/api/public/subscription](#post-apipublicsubscription)                                 | Create a public subscription.                  |
| PUT    | [/api/subscribers/lists](#put-apisubscriberslists)                                      | Modify subscriber list memberships.            |
| PUT    | [/api/subscribers/query/lists](#put-apisubscribersquerylists)                           | Bulk modify list memberships using SQL/Search queries. |
| PUT    | [/api/subscribers/{subscriber_id}](#put-apisubscriberssubscriber_id)                    | Update a specific subscriber.                  |
| PATCH  | [/api/subscribers/{subscriber_id}](#patch-apisubscriberssubscriber_id)                  | Partially update a specific subscriber.        |
| PUT    | [/api/subscribers/{subscriber_id}/blocklist](#put-apisubscriberssubscriber_idblocklist) | Blocklist a specific subscriber.               |
| PUT    | [/api/subscribers/blocklist](#put-apisubscribersblocklist)                              | Blocklist one or many subscribers.             |
| PUT    | [/api/subscribers/query/blocklist](#put-apisubscribersqueryblocklist)                   | Blocklist subscribers based on SQL expression. |
| DELETE | [/api/subscribers/{subscriber_id}](#delete-apisubscriberssubscriber_id)                 | Delete a specific subscriber.                  |
| DELETE | [/api/subscribers/{subscriber_id}/bounces](#delete-apisubscriberssubscriber_idbounces)  | Delete a specific subscriber's bounce records. |
| DELETE | [/api/subscribers](#delete-apisubscribers)                                              | Delete one or more subscribers.                |
| POST   | [/api/subscribers/query/delete](#post-apisubscribersquerydelete)                        | Delete subscribers based on SQL expression.    |

______________________________________________________________________

#### GET /api/subscribers

Retrieve all subscribers.

##### Query parameters

| Name                | Type   | Required | Description                                                           |
| :------------------ | :----- | :------- | :-------------------------------------------------------------------- |
| query               | string |          | Subscriber search by SQL expression.                                  |
| list_id             | int[]  |          | ID of lists to filter by. Repeat in the query for multiple values.    |
| subscription_status | string |          | Subscription status to filter by if there are one or more `list_id`s. |
| order_by            | string |          | Result sorting field. Options: name, status, created_at, updated_at.  |
| order               | string |          | Sorting order: ASC for ascending, DESC for descending.                |
| page                | number |          | Page number for paginated results.                                    |
| per_page            | number |          | Results per page. Set as 'all' for all results.                       |

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers?page=1&per_page=100' 
```

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers?list_id=1&list_id=2&page=1&per_page=100'
```

```shell
curl -u 'api_username:access_token' -X GET 'http://localhost:9000/api/subscribers' \
    --url-query 'page=1' \
    --url-query 'per_page=100' \
    --url-query "query=subscribers.name LIKE 'Test%' AND subscribers.attribs->>'city' = 'Bengaluru'"
```

##### Example Response

```
/* Detailed source-code truncated for AI context efficiency. */
```

______________________________________________________________________

#### GET /api/subscribers/{subscriber_id}

Retrieve a specific subscriber.

##### Parameters

| Name          | Type   | Required | Description      |
| :------------ | :----- | :------- | :--------------- |
| subscriber_id | Number | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers/1' 
```

##### Example Response

```json
{
    "data": {
        "id": 1,
        "created_at": "2020-02-10T23:07:16.199433+01:00",
        "updated_at": "2020-02-10T23:07:16.199433+01:00",
        "uuid": "ea06b2e7-4b08-4697-bcfc-2a5c6dde8f1c",
        "email": "john@example.com",
        "name": "John Doe",
        "attribs": {
            "city": "Bengaluru",
            "good": true,
            "type": "known"
        },
        "status": "enabled",
        "lists": [
            {
                "subscription_status": "unconfirmed",
                "id": 1,
                "uuid": "ce13e971-c2ed-4069-bd0c-240e9a9f56f9",
                "name": "Default list",
                "type": "public",
                "tags": [
                    "test"
                ],
                "created_at": "2020-02-10T23:07:16.194843+01:00",
                "updated_at": "2020-02-10T23:07:16.194843+01:00"
            }
        ]
    }
}
```
______________________________________________________________________

#### GET /api/subscribers/{subscriber_id}/export

Export a specific subscriber data that gives profile, list subscriptions, campaign views and link clicks information. Names of private lists are replaced with "Private list". 

##### Parameters

| Name          | Type   | Required | Description      |
| :------------ | :----- | :------- | :--------------- |
| subscriber_id | Number | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers/1/export' 
```

##### Example Response

```json
{
  "profile": [
    {
      "id": 1,
      "uuid": "c2cc0b31-b485-4d72-8ce8-b47081beadec",
      "email": "john@example.com",
      "name": "John Doe",
      "attribs": {
        "city": "Bengaluru",
        "good": true,
        "type": "known"
      },
      "status": "enabled",
      "created_at": "2024-07-29T11:01:31.478677+05:30",
      "updated_at": "2024-07-29T11:01:31.478677+05:30"
    }
  ],
  "subscriptions": [
    {
      "subscription_status": "unconfirmed",
      "name": "Private list",
      "type": "private",
      "created_at": "2024-07-29T11:01:31.478677+05:30"
    }
  ],
  "campaign_views": [],
  "link_clicks": []
}
```
______________________________________________________________________

#### GET /api/subscribers/{subscriber_id}/bounces

Get a specific subscriber bounce records.
##### Parameters

| Name          | Type   | Required | Description      |
| :------------ | :----- | :------- | :--------------- |
| subscriber_id | Number | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers/1/bounces' 
```

##### Example Response

```json
{
  "data": [
    {
      "id": 841706,
      "type": "hard",
      "source": "demo",
      "meta": {
        "some": "parameter"
      },
      "created_at": "2024-08-22T09:05:12.862877Z",
      "email": "thomas.hobbes@example.com",
      "subscriber_uuid": "137c0d83-8de6-44e2-a55f-d4238ab21969",
      "subscriber_id": 99,
      "campaign": {
        "id": 2,
        "name": "Welcome to listmonk"
      }
    },
    {
      "id": 841680,
      "type": "hard",
      "source": "demo",
      "meta": {
        "some": "parameter"
      },
      "created_at": "2024-08-19T14:07:53.141917Z",
      "email": "thomas.hobbes@example.com",
      "subscriber_uuid": "137c0d83-8de6-44e2-a55f-d4238ab21969",
      "subscriber_id": 99,
      "campaign": {
        "id": 1,
        "name": "Test campaign"
      }
    }
  ]
}
```

______________________________________________________________________

#### POST /api/subscribers

Create a new subscriber.

##### Parameters

| Name                     | Type       | Required | Description                                                                                                                   |
|:-------------------------|:-----------|:---------|:------------------------------------------------------------------------------------------------------------------------------|
| email                    | string     | Yes      | Subscriber's email address.                                                                                                   |
| name                     | string     | Yes      | Subscriber's name.                                                                                                            |
| status                   | string     | Yes      | Subscriber's status: `enabled`, `blocklisted`.                                                                                |
| lists                    | number\[\] |          | List of list IDs to subscribe to.                                                                                             |
| attribs                  | JSON       |          | Optional JSON object attributes for the subscriber that can be used in message templates. Example `{"location": "Somewhere"}` |
| preconfirm_subscriptions | bool       |          | If true, subscriptions are marked as confirmed and no opt-in emails are sent for double opt-in lists.                         |

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers' -H 'Content-Type: application/json' \
    --data '{"email":"subscriber@domain.com","name":"The Subscriber","status":"enabled","lists":[1],"attribs":{"city":"Bengaluru","projects":3,"stack":{"languages":["go","python"]}}}'
```

##### Example Response

```json
{
  "data": {
    "id": 3,
    "created_at": "2019-07-03T12:17:29.735507+05:30",
    "updated_at": "2019-07-03T12:17:29.735507+05:30",
    "uuid": "eb420c55-4cfb-4972-92ba-c93c34ba475d",
    "email": "subscriber@domain.com",
    "name": "The Subscriber",
    "attribs": {
      "city": "Bengaluru",
      "projects": 3,
      "stack": { "languages": ["go", "python"] }
    },
    "status": "enabled",
    "lists": [1]
  }
}
```

______________________________________________________________________

#### POST /api/subscribers/{subscribers_id}/optin

Sends opt-in confirmation email to subscribers.

##### Example Request

```shell
curl -u 'api_username:access_token' 'http://localhost:9000/api/subscribers/11/optin' -H 'Content-Type: application/json' \
--data {}
```

##### Example Response

```json
{
    "data": true
} 
```
______________________________________________________________________

#### POST /api/public/subscription

Create a public subscription, accepts both form encoded or JSON encoded body.

##### Parameters

| Name       | Type       | Required | Description                 |
| :--------- | :--------- | :------- | :-------------------------- |
| email      | string     | Yes      | Subscriber's email address. |
| name       | string     |          | Subscriber's name.          |
| list_uuids | string\[\] | Yes      | List of list UUIDs.         |

##### Example JSON Request

```shell
curl 'http://localhost:9000/api/public/subscription' -H 'Content-Type: application/json' \
    --data '{"email":"subscriber@domain.com","name":"The Subscriber","list_uuids": ["eb420c55-4cfb-4972-92ba-c93c34ba475d", "0c554cfb-eb42-4972-92ba-c93c34ba475d"]}'
```

##### Example Form Request

```shell
curl -u 'http://localhost:9000/api/public/subscription' \
    -d 'email=subscriber@domain.com' -d 'name=The Subscriber' -d 'l=eb420c55-4cfb-4972-92ba-c93c34ba475d' -d 'l=0c554cfb-eb42-4972-92ba-c93c34ba475d'
```

Note: For form request, use `l` for multiple lists instead of `lists`.

##### Example Response

```json
{
  "data": true
}
```

______________________________________________________________________

#### PUT /api/subscribers/lists

Modify subscriber list memberships.

##### Parameters

| Name            | Type       | Required           | Description                                                       |
| :-------------- | :--------- | :----------------- | :---------------------------------------------------------------- |
| ids             | number\[\] | Yes                | Array of user IDs to be modified.                                 |
| action          | string     | Yes                | Action to be applied: `add`, `remove`, or `unsubscribe`.          |
| target_list_ids | number\[\] | Yes                | Array of list IDs to be modified.                                 |
| status          | string     | Required for `add` | Subscriber status: `confirmed`, `unconfirmed`, or `unsubscribed`. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X PUT 'http://localhost:9000/api/subscribers/lists' \
-H 'Content-Type: application/json' \
--data-raw '{"ids": [1, 2, 3], "action": "add", "target_list_ids": [4, 5, 6], "status": "confirmed"}'
```

##### Example Response

```json
{
    "data": true
} 
```
______________________________________________________________________

#### PUT /api/subscribers/query/lists

Modify list memberships for multiple subscribers dynamically using a search query and/or SQL expression.

##### Parameters

| Name                | Type       | Required           | Description                                                                                     |
| :------------------ | :--------- | :----------------- | :---------------------------------------------------------------------------------------------- |
| action              | string     | Yes                | Action to be applied: `add`, `remove`, or `unsubscribe`.                                        |
| target_list_ids     | number\[\] | Yes                | Array of list IDs that the matching subscribers should be added to or removed from.              |
| query               | string     | No                 | SQL expression to filter subscribers (e.g., `subscribers.email LIKE '%@domain.com'`). |
| search              | string     | No                 | Free-text search string targeting name, email, or other general text attributes.                 |
| list_ids            | number\[\] | No                 | Optional list IDs to limit the query filter scope (only checks subscribers in these source lists). |
| status              | string     | Required for `add` | Subscription status to set when subscribing: `confirmed`, `unconfirmed`, or `unsubscribed`.    |
| subscription_status | string     | No                 | Optional subscription status filter to apply to the source lists specified in `list_ids`.       |

##### Example Requests

###### Subscribing Query Matches to a List
```shell
curl -u 'api_username:access_token' -X PUT 'http://localhost:9000/api/subscribers/query/lists' \
    -H 'Content-Type: application/json' \
    --data-raw '{
      "query": "subscribers.email LIKE '\''%@domain.com'\''",
      "action": "add",
      "target_list_ids": [3],
      "status": "confirmed"
}'

```

###### Removing Disqualified Subscribers from a List
```shell
curl -u 'api_username:access_token' -X PUT 'http://localhost:9000/api/subscribers/query/lists' \
    -H 'Content-Type: application/json' \
    --data-raw '{
      "query": "NOT subscribers.email LIKE '\''%@domain.com'\''",
      "action": "remove",
      "target_list_ids": [3]
}'
```

##### Example Response
```json
{
    "data": true
}
```

______________________________________________________________________

#### PUT /api/subscribers/{subscriber_id}

Update a specific subscriber.

> Refer to parameters from [POST /api/subscribers](#post-apisubscribers). Note: All parameters must be set, if not, the subscriber will be removed from all previously assigned lists.

______________________________________________________________________

#### PATCH /api/subscribers/{subscriber_id}

Partially update a subscriber. Only fields present in the request body are updated. Unlike PUT, omitting the `lists` field preserves existing list subscriptions. `PUT` treats empty `lists` as a signal to clear all subscriptions.

##### Parameters

| Name                     | Type       | Required | Description                                                                                                                       |
|:-------------------------|:-----------|:---------|:----------------------------------------------------------------------------------------------------------------------------------|
| email                    | string     |          | Subscriber's email address. Updated only if provided.                                                                             |
| name                     | string     |          | Subscriber's name. Updated only if provided.                                                                                      |
| status                   | string     |          | Subscriber's status: `enabled`, `disabled`, `blocklisted`. Updated only if provided.                                              |
| lists                    | number\[\] |          | Array of list IDs. If provided, replaces the subscriber's current list subscriptions. If omitted, existing subscriptions are kept. |
| attribs                  | JSON       |          | JSON object of subscriber attributes. If provided, merged with existing attributes.                                               |
| preconfirm_subscriptions | bool       |          | If true, subscriptions are marked as confirmed and no opt-in emails are sent for double opt-in lists.                             |

##### Example Request

```shell
curl -u 'api_username:access_token' -X PATCH 'http://localhost:9000/api/subscribers/1' \
    -H 'Content-Type: application/json' \
    --data '{"name":"Updated Name"}'
```

##### Example Response

```json
{
  "data": {
    "id": 1,
    "created_at": "2020-02-10T23:07:16.199433+01:00",
    "updated_at": "2020-03-10T16:37:17.228327+01:00",
    "uuid": "ea06b2e7-4b08-4571-b436-5c5cf31c5cd4",
    "email": "subscriber@domain.com",
    "name": "Updated Name",
    "attribs": {},
    "status": "enabled",
    "lists": [{
      "subscription_status": "unconfirmed",
      "id": 1,
      "uuid": "ce13e971-c2ed-4069-bd0c-240e9a9f56f9",
      "name": "Default list",
      "type": "public",
      "optin": "single"
    }]
  }
}
```

______________________________________________________________________

#### PUT /api/subscribers/{subscriber_id}/blocklist

Blocklist a specific subscriber.

##### Parameters

| Name          | Type   | Required | Description      |
| :------------ | :----- | :------- | :--------------- |
| subscriber_id | Number | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X PUT 'http://localhost:9000/api/subscribers/9/blocklist'
```

##### Example Response

```json
{
    "data": true
} 
```

______________________________________________________________________

#### PUT /api/subscribers/blocklist

Blocklist multiple subscriber.

##### Parameters

| Name | Type   | Required | Description      |
| :--- | :----- | :------- | :--------------- |
| ids  | Number | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X PUT 'http://localhost:8080/api/subscribers/blocklist' -H 'Content-Type: application/json' --data-raw '{"ids":[2,1]}'
```

##### Example Response

```json
{
    "data": true
} 
```

______________________________________________________________________

#### PUT /api/subscribers/query/blocklist

Blocklist subscribers based on SQL expression.

> Refer to the [querying and segmentation](../querying-and-segmentation.md#querying-and-segmenting-subscribers) section for more information on how to query subscribers with SQL expressions.

##### Parameters

| Name     | Type     | Required | Description                                  |
| :------- | :------- | :------- | :------------------------------------------- |
| query    | string   | Yes      | SQL expression to filter subscribers with.   |
| list_ids | []number | No       | Optional list IDs to limit the filtering to. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X POST 'http://localhost:9000/api/subscribers/query/blocklist' \
-H 'Content-Type: application/json' \
--data-raw '{"query":"subscribers.name LIKE \'John Doe\' AND subscribers.attribs->>'\''city'\'' = '\''Bengaluru'\''"}'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/subscribers/{subscriber_id}

Delete a specific subscriber.

##### Parameters

| Name          | Type   | Required | Description      |
| :------------ | :----- | :------- | :--------------- |
| subscriber_id | Number | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/subscribers/9'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/subscribers/{subscriber_id}/bounces

Delete a subscriber's bounce records

##### Parameters

| Name | Type          | Required | Description      |
| :--- | :------------ | :------- | :--------------- |
| id   | subscriber_id | Yes      | Subscriber's ID. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/subscribers/9/bounces'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### DELETE /api/subscribers

Delete one or more subscribers.

##### Parameters

| Name | Type       | Required | Description                |
| :--- | :--------- | :------- | :------------------------- |
| id   | number\[\] | Yes      | Array of subscriber's IDs. |

##### Example Request

```shell
curl -u 'api_username:access_token' -X DELETE 'http://localhost:9000/api/subscribers?id=10&id=11'
```

##### Example Response

```json
{
    "data": true
}
```

______________________________________________________________________

#### POST /api/subscribers/query/delete

Delete subscribers based on SQL expression.

##### Parameters

| Name     | Type     | Required | Description                                                        |
| :------- | :------- | :------- | :----------------------------------------------------------------- |
| query    | string   | No       | SQL expression to filter subscribers with.                         |
| list_ids | []number | No       | Optional list IDs to limit the filtering to.                       |
| all      | bool     | No       | When set to `true`, ignores any query and deletes all subscribers. |


##### Example Request

```shell
curl -u 'api_username:access_token' -X POST 'http://localhost:9000/api/subscribers/query/delete' \
-H 'Content-Type: application/json' \
--data-raw '{"query":"subscribers.name LIKE \'John Doe\' AND subscribers.attribs->>'\''city'\'' = '\''Bengaluru'\''"}'
```

##### Example Response

```json
{
    "data": true
}
```