---
title: lists.sr.ht API reference
---
The lists.sr.ht API allows you to browse, create, and subscribe to mailing lists
on lists.sr.ht programmatically. This API follows the [standard sourcehut API
conventions](../api-conventions.md).
## Authentication
Authentication is done via the [meta.sr.ht OAuth
flow](https://man.sr.ht/meta.sr.ht/oauth-api.md). The following OAuth scopes are
available for lists.sr.ht:
- **emails:read**: read emails received from lists.sr.ht users
- **lists:read**, **list:write**: read & write your mailing lists
- **subs:read**, **subs:write**: read & write your subscriptions
- **patches:read**, **patches:write**: read & write patchsets on lists
## Resources
### Email resource
```json
{
"id": integer,
"created": "timestamp",
"subject": "message subject",
"message_id": "value of the Message-ID header",
"parent_id": integer or null,
"thread_id": integer,
"list": { short form list resource },
"sender": { short form user resource } or null,
"is_patch": boolean,
"is_request_pull": boolean,
"replies": integer,
"participants": integer,
"envelope": "original email"
}
```
**Notes**
- The short form omits `is_patch`, `is_request_pull`, `replies`, `participants`,
and `envelope`.
- The sender is null if the sender's email address could not be associated with
a sr.ht account.
### Mailing list resource
```json
{
"created": "timestamp",
"updated": "timestamp",
"name": "name of this list",
"owner": { short form user resource },
"description": "list description (markdown)",
"permissions": {
"nonsubscriber": [ list of permissions ],
"subscriber": [ list of permissions ],
"account": [ list of permissions ]
}
}
```
**Notes**
- The permissions which may appear in each `permissions` field are "browse",
"reply", and "post".
- The short form omits everything except for name and owner.
### Subscription resource
```json
{
"id": integer,
"created": "timestamp",
"list": { short form list resource }
}
```
### Patchset resource
```json
{
"id": integer,
"created": "timestamp",
"updated": "timestamp",
"subject": "patchset subject",
"prefix": "subject prefix",
"version": integer,
"status": "patchset status enum",
"list": { short form list resource },
"cover_letter": { short form email resource } or null,
"superseded_by": { short form patchset resource } or null
}
```
**Notes**
- The status field may be one of `proposed`, `needs_revision`, `superseded`,
`approved`, `rejected`, or `applied`.
- The patchset subject is extracted from the cover letter if present, otherwise
from the subject of the first patch.
- The subject prefix, in the example of `[PATCH foobar] Add foo to bar`, is
"foobar".
## Endpoints
**Note**: in all routes, `:username` may be substituted with an email address,
and `:email-id` may be the email's either of the "id" or "message_id" values.
### GET /api/user/:username
Retrieves a user resource.
### GET /api/user
Equivalent to [/api/user/:username](#GET-apiuserusername), implies the authenticated
user.
### GET /api/user/:username/emails
List of [email resources](#email-resource) received from this user.
**OAuth scope**: `emails:read`
### GET /api/emails
Equivalent to [/api/user/:username/emails](#GET-apiuserusernameemails), implies the
authenticated user.
**OAuth scope**: `emails:read`
### GET /api/emails/:email-id
Retrieves an [email resource](#email-resource).
**OAuth scope**: `emails:read`
### GET /api/user/:username/emails/:email-id
Equivalent to [GET /api/emails/:email-id](#GET-apiemailsemail-id); `username` is
discarded.
**OAuth scope**: `emails:read`
### GET /api/thread/:email-id
Retrieves an array of each email implicated in the thread identified by its
first message's `:email-id`.
**OAuth scope**: `emails:read`
**Response**
```json
[
{ short form email resource },
...
]
```
### GET /api/user/:username/thread/:email-id
Equivalent to [GET /api/thread/:email-id](#GET-apithreademail-id); `username` is
discarded.
**OAuth scope**: `emails:read`
### GET /api/user/:username/lists
List of [mailing list resources](#mailing-list-resource) owned by this user.
**OAuth scope**: `lists:read`
### GET /api/lists
Equivalent to [/api/user/:username/lists](#GET-apiuserusernamelists), implies the
authenticated user.
**OAuth scope**: `lists:read`
### POST /api/lists
Creates a new [mailing list resource](#mailing-list-resource).
**OAuth scope**: `lists:write`
**Request body**
```json
{
"name": "mailing list name",
"description": "mailing list description (markdown)" (optional)
}
```
**Response**
The new [mailing list resource](#mailing-list-resource).
### GET /api/user/:username/lists/:list-name
Retrieves a [mailing list resource](#mailing-list-resource).
**OAuth scope**: `lists:read`
### GET /api/lists/:list-name
Equivalent to [/api/user/:username/lists/:list-name](#GET-apiuserusernamelistslist-name),
implies the authenticated user.
**OAuth scope**: `lists:read`
### PUT /api/lists/:list-name
Updates a [mailing list resource](#mailing-list-resource).
**OAuth scope**: `lists:write`
**Request body**
```json
{
"description": "mailing list description (markdown)" (optional)
}
```
**Response**
The updated [mailing list resource](#mailing-list-resource).
### GET /api/user/:username/lists/:list-name/posts
List of [email resources](#email-resource) posted to this list.
**OAuth scope**: `lists:read`
### GET /api/lists/:list-name/posts
Equivalent to
[/api/user/:username/lists/:list-name/posts](#GET-apiuserusernamelistslist-nameposts),
implies the authenticated user.
**OAuth scope**: `lists:read`
### GET /api/user/:username/lists/:list-name/patchsets
List of [patchset resources](#patchset-resource) posted to this list.
**OAuth scope**: `patches:read`
### GET /api/user/:username/lists/:list-name/patchsets
Equivalent to
[/api/user/:username/lists/:list-name/patchsets](#GET-apiuserusernamelistslist-namepatchsets),
implies the authenticated user.
**OAuth scope**: `patches:read`
### GET /api/user/:username/lists/:list-name/patchsets/:id
Retrieves a [patchset resource](#patchset-resource).
**OAuth scope**: `patches:read`
### GET /api/user/:username/lists/:list-name/patchsets/:id
Equivalent to
[/api/user/:username/lists/:list-name/patchsets/:id](#GET-apiuserusernamelistslist-namepatchsetsid),
implies the authenticated user.
**OAuth scope**: `patches:read`
### PUT /api/user/:username/lists/:list-name/patchsets/:id
Updates a [patchset resource](#patchset-resource).
**OAuth scope**: `patches:read`
**Request body**
```json
{
"status": "patchset status enum" (optional)
}
```
**Response**
The updated [patchset resource](#patchset-resource).
### PUT /api/user/:username/lists/:list-name/patchsets/:id
Equivalent to
[/api/user/:username/lists/:list-name/patchsets/:id](#GET-apiuserusernamelistslist-namepatchsetsid),
implies the authenticated user.
**OAuth scope**: `patches:read`
### GET /api/user/:username/lists/:list-name/patchsets/:id/patches
List of [email resources](#email-resource) making up the set of patches included
in this patchset.
**OAuth scope**: `patches:read`
### GET /api/user/:username/lists/:list-name/patchsets/:id/patches
Equivalent to
[/api/user/:username/lists/:list-name/patchsets/:id/patches](#GET-apiuserusernamelistslist-namepatchsetsidpatches),
implies the authenticated user.
**OAuth scope**: `patches:read`
### GET /api/subscriptions
List of [subscription resources](#subscription-resources)
**OAuth scope**: `subs:read`
### POST /api/subscriptions
Create a new [subscription resources](#subscription-resources)
**OAuth scope**: `subs:write`
**Request body**
```json
{
"list": "~owner/list-name"
}
```
**Response**
The new [subscription resource](#subscription-resource).
### GET /api/subscriptions/:sub-id
Retrieves a [subscription resource](#subscription-resource).
**OAuth scope**: `subs:read`
### DELETE /api/subscriptions/:sub-id
Deletes this [subscription resource](#subscription-resource).
**OAuth scope**: `subs:write`
## Webhooks
### /api/user/...
Webhook for user events. Includes the [standard webhook
endpoints](../api-conventions.md#webhooks)
#### email:received
Issued when lists.sr.ht receives an email from this user.
**OAuth scope**: `emails:read`
**Request body**
The new [email resource](#email-resource).
#### list:create
Issued when the user creates a new mailing list.
**OAuth scope**: `lists:read`
**Request body**
The new [mailing list resource](#mailing-list-resource).
#### subscription:create
Issued when the user subscribes to a mailing list.
**OAuth scope**: `subs:read`
**Request body**
The new [subscription resource](#subscription-resource).
#### subscription:remove
Issued when the user unsubscribes from a mailing list.
**OAuth scope**: `subs:read`
**Request body**
```json
{
"id": integer ID of the affected subscription resource
}
```
### /api/user/:username/lists/:list-name/...
Webhook for mailing list events. Includes the [standard webhook
endpoints](../api-conventions.md#webhooks)
#### patchset:received
Issued when a complete patchset is received.
**OAuth scope**: `patches:read`
**Request body**
The new [patchset resource](#patchset-resource).
#### post:received
Issued when a new email is posted to this list.
**OAuth scope**: `lists:read`
**Request body**
The new [email resource](#email-resource).
#### list:update
Issued when the list details are updated.
**OAuth scope**: `lists:read`
**Request body**
The updated [mailing list resource](#mailing-list-resource).