Mail projects
A project owns its outbound attempts and has a Management membership for each authorized principal. The selected workspace determines the effective principal used for access. A personal project initially belongs to its creator; an organization project initially belongs to that organization's canonical principal. The real caller remains the recorded creation actor.
All routes here use authenticated POST JSON. Request fields are strict;
send the documented fields plus optional organization-selection metadata.
List and create
POST /projects/list accepts {} and requires project.list. It returns
data.items as an array of accessible project contexts and data.can_create
as a boolean. It has no limit, cursor, or page-number input. A project you
cannot access does not appear in this list.
POST /projects/create accepts:
{"name":"Transactional mail"}
name must be a string, nonblank when trimmed, and at most 255 bytes as
submitted. The stored name is trimmed. Creation requires project.create
and returns the new project context. The project starts with an active Owner
membership for the effective principal. For organization creation,
organization capability selections also need to authorize creation.
Load current context
POST /projects/context accepts:
{"project_id":"<project-uuid>"}
It requires project.view and returns these data fields:
| Field | Meaning |
|---|---|
project |
Project record, including its id, name, and creation actor. |
membership |
Effective caller membership: id, principal, role, status. |
management_group_id |
ID of the project's Management group. |
capabilities |
Exact actions currently granted to this effective principal. |
Project roles are owner, admin, and member. Owners and Admins have
protected project-management rights; Members have protected list, view,
and leave rights. Sending and log actions come from role defaults or custom
capability selections. Organization requests intersect these rights with
verified organization grants. A role name is therefore insufficient to
predict which actions will succeed. Read returned capabilities and handle
authorization changes on each request.
Use project-member management to add an existing active service principal, edit membership, or change optional capabilities. Service membership and project membership are separate requirements.
Review and delete
An Owner with project.delete can request a deletion summary:
{"project_id":"<project-uuid>","include_deletion_summary":true}
include_deletion_summary must be a JSON boolean; it defaults to false.
When true, the context includes deletion_summary with integer counts
total, sent, queued, and failed. This is a current review snapshot,
not a reservation against later changes.
POST /projects/delete requires the exact project ID twice:
{"project_id":"<project-uuid>","confirm_project_id":"<project-uuid>"}
The effective principal must still be an Owner with project.delete when the
operation executes. Success returns
data: {"deleted":true,"project_id":"<project-uuid>"}. Deletion removes the
project and its send-log history and project access associations. It cannot
recall mail already queued or delivered. Shared access resources still used
by other projects remain available to those projects.
A mismatched confirmation returns 400; denied authority returns 403.
If project access changes during a conflicting operation, 409 can require
reloading context before trying again. Do not blindly retry deletion without
reconfirming the selected project.