Send your application's own email - a support reply, a sign-in code - on behalf of a subscribing workspace, through Connect's sending identity and its bounce and complaint suppression list.
Send your application's own email - a helpdesk reply, a portal sign-in code - for a workspace that subscribes to you, without an email provider account of your own.
Who it is from
Every email leaves from Connect's sending address, support@cosmoops.com, under a display name: the fromName you send, or the workspace's name when you send none. You choose the name and the replyTo, never the address - so a customer's answer reaches your inbound address, and nobody can send as Connect's billing or sign-in mail.
Threads
Mail clients thread on In-Reply-To and References and nothing else. Every send answers the messageId the email actually left under - Connect's mail provider replaces any Message-ID you propose, so store the one in the response, not your own. Reply with headers.inReplyTo set to the message you are answering and headers.references to the thread so far.
Addresses that cannot receive
Connect keeps one suppression list for the whole platform: an address that hard-bounced or marked mail as spam is never sent to again until an operator clears it. Your mail shares that list and that reputation. A suppressed recipient is skipped, the others are sent, and the skipped ones come back in suppressed - show the address as undeliverable rather than retrying, because a retry is skipped the same way.
Budgets
Per key, and per key and recipient - a ticket thread is a few replies an hour. Send an Idempotency-Key with every call: a retried send without one is a second copy in somebody's inbox.
Endpoints
POST /api/v1/application/email/send
Send an email on a workspace's behalf
Scope email:send · Rate limit 120 requests / min per key, 30 requests / hour per key+recipient
Sends your application's own email - a support reply, a portal sign-in code - for a workspace that subscribes to your application. Server-to-server only: a request carrying a member's session token is refused.
Implementation
1. Prerequisite - an API key scoped to email:send.
2. Send - html and text are both required (256 KB each); to and cc take up to 10 addresses each:
curl -X POST https://connect.cosmoops.com/api/v1/application/email/send \
-H "Authorization: Bearer YOUR_API_KEY_PLAINTEXT" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ticket-1042-reply-3" \
-d '{"workspaceId":"WORKSPACE_ID","to":["priya@example.com"],"subject":"Re: Refund for order 1042","html":"<p>Done - it is on its way.</p>","text":"Done - it is on its way.","replyTo":"t-1042@in.example.com","fromName":"Acme Support","headers":{"inReplyTo":"<CAF0x9@mail.gmail.com>","references":"<CAF0x9@mail.gmail.com>"}}'3. The sender. Every email leaves from Connect's address (support@cosmoops.com) with fromName as the display name - the workspace's name when you send none. Put your own inbound address in replyTo to receive the answer.
4. Threading. Store the response's messageId: it is the Message-ID the email actually left under (Connect's mail provider replaces any headers.messageId you send), and a customer's reply names it in In-Reply-To. Send the next reply with headers.inReplyTo and headers.references set from the thread. Header values may not contain line breaks.
5. Suppression. An address that hard-bounced or marked Connect's mail as spam is skipped and listed in suppressed; the rest are sent. When every recipient is suppressed nothing is sent and the call still answers 201 - show the customer's address as undeliverable rather than retrying.
Errors
validation_error (400 - bad body, too many recipients, an oversize body, or a line break in a header value), forbidden (403 - key missing email:send, a session token was forwarded, or your application is not installed in that workspace), idempotency_key_reused/request_in_progress (409), rate_limited (429 - per key, and per key and recipient), delivery_failed (502 - retry).
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
workspaceId | string | yes | |
to | array | yes | |
cc | array | no | |
subject | string | yes | |
html | string | yes | |
text | string | yes | |
replyTo | email | no | |
fromName | string | no | |
headers | object | no |
Responses
| Status | Meaning |
|---|---|
201 | Sent (or every recipient suppressed - see suppressed) |
400 | validation_error - bad body, recipient cap, oversize body, or a line break in a header |
403 | forbidden - key missing email:send, a forwarded session, or not installed in that workspace |
409 | idempotency_key_reused / request_in_progress |
429 | rate_limited |
502 | delivery_failed - the mail provider refused the message; retry |
Response body
| Field | Type | Required | Notes |
|---|---|---|---|
messageId | string | yes | |
suppressed | array | yes |
Send your application's own Meta-approved WhatsApp templates to a workspace's customers, through Connect's WhatsApp sender - and check whether a template is live before offering it.
Push notifications
Put a notification on a member's lock screen. Connect holds the VAPID keys, the devices and the member's own preferences - your application supplies a title, a body and a path.