Workspace API

Client emails

Client emails endpoints of the Zanfia Workspace API, with schemas and code samples.

4 min readLast updated Oct 23, 2026

One-off, personal e-mails from you to one customer (the customer card’s “Send email”): write a draft, review or edit it, then send it with the send route. This is transactional correspondence, not a campaign, so it goes to the customer’s address regardless of their newsletter subscription; addresses suppressed after a hard bounce or a spam complaint are still skipped by the mailer. Sending is real and cannot be recalled. The sender identity (From name, Reply-To, optional custom From on a verified sending domain) is resolved from your workspace defaults when the draft is created and can be overridden per draft. contentMarkdown is Markdown (max 50 000 chars), subject max 200 chars; branded wraps the e-mail in your branded frame (default: a plain personal note). A sent e-mail is immutable history; a failed hand-off (status: failed, reason in failureReason) stays editable and re-sendable. Refusals carry a machine-readable error (client-not-found, email-not-found, already-sent, invalid-field, no-recipient, send-failed, daily-limit-reached) with the detail in message. Sending through the API or MCP is limited per workspace per day (100 unless your plan sets another, reset at midnight Warsaw time); over it the send route answers 429 daily-limit-reached with a Retry-After header (seconds until the reset). E-mails sent from the dashboard are not limited. All routes require a Authorization: Bearer header — see Authentication.

List client e-mails (workspace feed)

GET/client-emails

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Query Parameters

limit?integer
Range1 <= value <= 500
Default200

Response Body

application/json

application/json

curl -X GET "https://example.com/client-emails"
{  "emails": [    {      "id": "string",      "clientId": "string",      "recipientEmail": "string",      "recipientName": "string",      "subject": "string",      "contentMarkdown": "string",      "sender": {        "fromName": "string",        "replyTo": "string",        "fromEmail": "string"      },      "branded": true,      "status": "draft",      "createdBy": {        "kind": "staff",        "uid": "string"      },      "createdAt": "string",      "updatedAt": "string",      "sentAt": "string",      "failureReason": "string"    }  ]}
{  "error": "string",  "message": "string"}

List one client's e-mails

GET/clients/{clientId}/emails

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

Response Body

application/json

application/json

curl -X GET "https://example.com/clients/string/emails"
{  "emails": [    {      "id": "string",      "clientId": "string",      "recipientEmail": "string",      "recipientName": "string",      "subject": "string",      "contentMarkdown": "string",      "sender": {        "fromName": "string",        "replyTo": "string",        "fromEmail": "string"      },      "branded": true,      "status": "draft",      "createdBy": {        "kind": "staff",        "uid": "string"      },      "createdAt": "string",      "updatedAt": "string",      "sentAt": "string",      "failureReason": "string"    }  ]}
{  "error": "string",  "message": "string"}

Create a client e-mail draft

POST/clients/{clientId}/emails

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Subject and body may be empty at draft time; omitted sender fields use the workspace defaults.

Response Body

application/json

application/json

curl -X POST "https://example.com/clients/string/emails" \  -H "Content-Type: application/json" \  -d '{    "subject": "string",    "contentMarkdown": "string"  }'
{  "email": {    "id": "string",    "clientId": "string",    "recipientEmail": "string",    "recipientName": "string",    "subject": "string",    "contentMarkdown": "string",    "sender": {      "fromName": "string",      "replyTo": "string",      "fromEmail": "string"    },    "branded": true,    "status": "draft",    "createdBy": {      "kind": "staff",      "uid": "string"    },    "createdAt": "string",    "updatedAt": "string",    "sentAt": "string",    "failureReason": "string"  }}
{  "error": "string",  "message": "string"}

Update a client e-mail draft

PATCH/clients/{clientId}/emails/{emailId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

emailId*string

Client e-mail id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Drafts and failed hand-offs only; an explicit null clears sender.replyTo / sender.fromEmail.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/clients/string/emails/string" \  -H "Content-Type: application/json" \  -d '{}'
{  "email": {    "id": "string",    "clientId": "string",    "recipientEmail": "string",    "recipientName": "string",    "subject": "string",    "contentMarkdown": "string",    "sender": {      "fromName": "string",      "replyTo": "string",      "fromEmail": "string"    },    "branded": true,    "status": "draft",    "createdBy": {      "kind": "staff",      "uid": "string"    },    "createdAt": "string",    "updatedAt": "string",    "sentAt": "string",    "failureReason": "string"  }}
{  "error": "string",  "message": "string"}

Delete a client e-mail draft

DELETE/clients/{clientId}/emails/{emailId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

emailId*string

Client e-mail id

Response Body

application/json

application/json

curl -X DELETE "https://example.com/clients/string/emails/string"
{  "deleted": true}
{  "error": "string",  "message": "string"}

Delete client email drafts

POST/client-emails/delete-drafts

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /client-emails/delete-drafts — bulk delete of drafts (and failed hand-offs) by ids, by subject, or all; sent e-mails are never touched. preview: true deletes nothing and returns the count + sample subjects.

Response Body

application/json

application/json

curl -X POST "https://example.com/client-emails/delete-drafts" \  -H "Content-Type: application/json" \  -d '{    "scope": "ids"  }'
{  "matchedCount": 0,  "deletedCount": 0,  "sampleSubjects": [    "string"  ],  "previewIds": [    "string"  ]}
{  "error": "string",  "message": "string"}

Send a client e-mail

POST/clients/{clientId}/emails/{emailId}/send

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

emailId*string

Client e-mail id

Response Body

application/json

application/json

curl -X POST "https://example.com/clients/string/emails/string/send"
{  "email": {    "id": "string",    "clientId": "string",    "recipientEmail": "string",    "recipientName": "string",    "subject": "string",    "contentMarkdown": "string",    "sender": {      "fromName": "string",      "replyTo": "string",      "fromEmail": "string"    },    "branded": true,    "status": "draft",    "createdBy": {      "kind": "staff",      "uid": "string"    },    "createdAt": "string",    "updatedAt": "string",    "sentAt": "string",    "failureReason": "string"  }}
{  "error": "string",  "message": "string"}

Was this article helpful?

Related articles

Spotted something off? Tell us at support@zanfia.com.