Projects
From the Workspaces & Projects API reference. Requests use the base URL https://app.warmerly.com/api/v1 and an API key, see Authentication.
A project hangs off a workspace and is what campaigns, mailboxes, and inbox data attach to via X-Project-Id. Each workspace has exactly one project. Unlike the workspace/member endpoints above, listing and creating projects operates on your active workspace rather than a workspace ID in the URL: the one named in X-Workspace-Id if you belong to it, otherwise your own workspace. GET /projects also accepts a workspaceId query parameter to list another workspace you belong to (a workspace you are not a member of returns 403 forbidden).
#List projects
GET /projects{
"projects": [
{
"id": "2b6e1c3d-...",
"name": "Default",
"slug": "default",
"description": null,
"color": null,
"icon": null,
"createdAt": "2026-01-10T12:00:00.000Z",
"campaignCount": 3,
"accountCount": 5
}
]
}If your active workspace has no projects yet, a default one is created automatically before the list is returned, so this endpoint never returns an empty array.
#Create a project
POST /projects| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Project name, at least 1 character. |
slug | string | Yes | Lowercase letters, numbers, and hyphens only (^[a-z0-9-]+$). A random suffix is appended automatically if the slug is already taken. |
description | string | No | Up to 2000 characters. |
color | string | No | Up to 32 characters. |
icon | string | No | Up to 64 characters. |
defaultTimezone | string | No | Up to 64 characters. |
curl https://app.warmerly.com/api/v1/projects \
-X POST \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Q3 Outbound", "slug": "q3-outbound" }'{
"project": {
"id": "9d4f2a11-...",
"name": "Q3 Outbound",
"slug": "q3-outbound",
"workspaceId": "8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a",
"userId": "3c2b1a09-...",
"description": null,
"color": null,
"icon": null,
"defaultTimezone": null,
"createdAt": "2026-07-01T09:00:00.000Z"
}
}userId is the user who created the project. 201 Created on success. Returns 409 conflict if the active workspace already has a project, a workspace can only ever have one.
#Get a project
GET /projects/{id}Returns the project. Requires membership in the project's workspace (403 forbidden otherwise, 404 not_found if the project does not exist).
{
"project": {
"id": "9d4f2a11-...",
"name": "Q3 Outbound",
"slug": "q3-outbound",
"workspaceId": "8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a",
"userId": "3c2b1a09-...",
"description": null,
"color": null,
"icon": null,
"defaultTimezone": null,
"createdAt": "2026-07-01T09:00:00.000Z"
}
}#Project stats
GET /projects/{id}/statsA rollup for one project: what the dashboard's project switcher shows.
{
"project": { "id": "…", "name": "SaaS Outreach", "slug": "saas-outreach-05adc35c", "workspaceId": "…", "userId": "…" },
"campaigns": { "total": 3, "active": 2 },
"accounts": { "total": 12 },
"leads": { "total": 145 },
"emails": { "sent": 300, "replied": 17, "replyRate": 5.7 }
}Requires membership in the project's workspace. accounts.total counts every mailbox attached to the project, so it can be higher than accountCount from GET /projects, which counts only mailboxes you connected yourself. replyRate is a percentage with one decimal place, of real campaign sends, not a warmup figure (see How warmup works for why the two must not be mixed).