Workspaces
Multi-workspace support for agencies and teams — share campaigns and contacts across members
Workspaces let agencies and teams operate multiple shared environments under one account. Each workspace has its own campaigns, contacts, and templates — members can be invited with role-based access.
Authentication
Workspace endpoints use a session cookie (dashboard UI) and are not available via API key. These routes live under /api/*, so the full base is https://api.misar.io/mail/api.
Roles
| Role | Capabilities |
|---|---|
owner | Assigned to the workspace creator. Full access — manage members, campaigns, and contacts |
admin | Manage members (invite/remove), campaigns, and contacts |
member | Create and run campaigns, add contacts — cannot invite or remove members |
owner is assigned automatically to whoever creates the workspace and cannot be granted through the invite endpoint — invites accept only admin or member.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/workspaces | List workspaces you own or belong to |
POST | /api/workspaces | Create a new workspace |
GET | /api/workspaces/:id/members | Get a workspace with its members |
POST | /api/workspaces/:id/members | Invite a member by email (admin only) |
DELETE | /api/workspaces/:id/members?memberId=:memberId | Remove a member (admin only) |
List workspaces
/mail/workspacesReturns all workspaces you own plus workspaces you are an active member of.
Response fields
workspacesArray<object>Workspaces you own or belong to. Each includes id, name, slug, owner_id, plan, and created_at.
curl https://api.misar.io/mail/workspaces \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"workspaces": [
{
"id": "ws-uuid-...",
"name": "Acme Agency",
"slug": "acme-agency-1710000000000",
"owner_id": "user-uuid-...",
"plan": "free",
"created_at": "2026-03-01T00:00:00Z"
}
]
}Create a workspace
/mail/workspacesCreate a new workspace. The creator is automatically added as the owner member. The slug is generated server-side from the name — it cannot be supplied.
Request body
namestringbodyrequiredDisplay name (2–100 chars).
Response fields
okbooleantrue when the workspace was created.
workspaceobjectThe created workspace: id, name, slug, owner_id, plan, created_at.
curl -X POST https://api.misar.io/mail/workspaces \
-H "Cookie: sb-access-token=YOUR_SESSION" \
-H "Content-Type: application/json" \
-d '{ "name": "Client Alpha" }'{
"ok": true,
"workspace": {
"id": "ws-new-uuid-...",
"name": "Client Alpha",
"slug": "client-alpha-1710000000000",
"owner_id": "your-user-uuid-...",
"plan": "free",
"created_at": "2026-04-13T10:00:00Z"
}
}Get a workspace with members
/mail/workspaces/:id/membersReturns the workspace and all of its members (excluding removed ones). Requires you to be the owner or an active member — otherwise 404.
Path parameters
idstringpathrequiredUUID of the workspace.
Response fields
workspaceobjectThe workspace: id, name, slug, owner_id, plan, created_at.
membersArray<object>Members. Each includes id, workspace_id, user_id, invited_email, role, status, and created_at. user_id is null for pending invites that have not yet been claimed.
curl https://api.misar.io/mail/workspaces/ws-uuid-.../members \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"workspace": {
"id": "ws-uuid-...",
"name": "Acme Agency",
"slug": "acme-agency-1710000000000",
"owner_id": "user-uuid-...",
"plan": "free",
"created_at": "2026-03-01T00:00:00Z"
},
"members": [
{
"id": "wm-uuid-...",
"workspace_id": "ws-uuid-...",
"user_id": "user-uuid-...",
"invited_email": "priya@example.com",
"role": "owner",
"status": "active",
"created_at": "2026-03-01T00:00:00Z"
},
{
"id": "wm-uuid-2...",
"workspace_id": "ws-uuid-...",
"user_id": null,
"invited_email": "ravi@example.com",
"role": "admin",
"status": "invited",
"created_at": "2026-03-15T00:00:00Z"
}
]
}Invite a member
/mail/workspaces/:id/membersInvite a user to the workspace by email. Requires the admin role. If the email matches an existing MisarMail user they are added as active; otherwise a pending invite (status: "invited") is created.
Path parameters
idstringpathrequiredUUID of the workspace.
Request body
emailstringbodyrequiredInvitee's email address.
rolestringbodydefault: memberadmin or member. owner cannot be assigned via invite.
Response fields
okbooleantrue when the invite succeeded.
memberobjectThe created or updated member row: id, workspace_id, user_id, invited_email, role, status, created_at.
curl -X POST https://api.misar.io/mail/workspaces/ws-uuid-.../members \
-H "Cookie: sb-access-token=YOUR_SESSION" \
-H "Content-Type: application/json" \
-d '{ "email": "newhire@example.com", "role": "member" }'{
"ok": true,
"member": {
"id": "wm-new-uuid-...",
"workspace_id": "ws-uuid-...",
"user_id": null,
"invited_email": "newhire@example.com",
"role": "member",
"status": "invited",
"created_at": "2026-04-13T10:00:00Z"
}
}Remove a member
/mail/workspaces/:id/membersRemove a member from the workspace. Requires the admin role. The member is identified by the memberId query parameter — the id of the workspace_members row (from the members list), not a user ID. Removal is a soft delete (status set to removed).
Path parameters
idstringpathrequiredUUID of the workspace.
Query parameters
memberIdstringqueryrequiredUUID of the member row to remove.
Response fields
okbooleantrue when the member was removed.
curl -X DELETE "https://api.misar.io/mail/workspaces/ws-uuid-.../members?memberId=wm-uuid-..." \
-H "Cookie: sb-access-token=YOUR_SESSION"{ "ok": true }