POST /api/v1/topics
Creates a topic. Answers 201 with the created topic — its id is the topicId you attach to a
campaign or a sequence.
A name already taken — case-insensitive, so Freelancing collides with freelancing —
answers 409.
Authorization
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Refused — 403 |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | 1 to 50 characters |
json
{"name": "freelancing"}Example
bash
curl -X POST -H "x-api-key: $AGENTMAIL_API_KEY" -H "content-type: application/json" \
-d '{"name":"freelancing"}' \
"https://www.agentsmail.io/api/v1/topics"Response
201 Created— the created topic.400 Bad Request— the name is missing, empty or over 50 characters;detailscarries the field-level issues.401 Unauthorized— missing or invalid key, or its owner left the organization.403 Forbidden— the key's owner is amemberof the organization, not anadmin.409 Conflict— another topic already carries that name, case ignored. Nothing was created; list the topics and reuse the existing id.429 Too Many Requests— over 120 requests in a minute for this key.
Response fields
| Field | Type | Description |
|---|---|---|
success | boolean | Indicates if the operation was successful |
data.id | string | Unique identifier for the topic |
data.name | string | Name of the topic, unique in the organization |
data.createdAt | string | ISO creation date |
data.updatedAt | string | ISO date of the last change |
Example response
json
{
"success": true,
"data": {
"id": "7c2e4b19",
"name": "freelancing",
"createdAt": "2026-08-23T10:22:05.000Z",
"updatedAt": "2026-08-23T10:22:05.000Z"
}
}Agent recipe
Reuse before creating — a second call for a name already taken just costs you a409:
js
const existing = await list('/api/v1/topics')
const topic =
existing.data.find((t) => t.name.toLowerCase() === 'freelancing') ??
(await post('/api/v1/topics', {name: 'freelancing'})).data
await post('/api/v1/campaigns', {
name: 'Freelance news',
subject: 'This month for freelancers',
templateId,
listId,
topicId: topic.id,
})Notes
- Creating a topic changes nothing on its own. It starts mattering the day a campaign or a sequence carries it.