runlot
ReferenceAPI

email

Covers the 7 API operations in the email category.

MethodPathDescription
POST/v1/hooks/sesSES bounce, complaint and delivery webhook (called by SNS, docs/email.md §6.2)
GET/v1/orgs/{orgSlug}/projects/{projectName}/emailEmail status (runlot email)
POST/v1/orgs/{orgSlug}/projects/{projectName}/emailTurn on email (the deploy reads "email": true and calls this)
DELETE/v1/orgs/{orgSlug}/projects/{projectName}/emailTurn off email (runlot email delete)
GET/v1/orgs/{orgSlug}/projects/{projectName}/email/logMail log (runlot email log)
GET/v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}Metadata for one message
GET/v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}/rawRaw message (message/rfc822)

POST /v1/hooks/ses

This is not a path you call. Amazon SNS delivers SES events here through an HTTPS subscription. Authentication is not a token but the SNS signature — it is accepted only when the certificate URL is https on sns.<region>.amazonaws.com and the topic matches the server's RUNLOT_SES_SNS_TOPIC_ARN (otherwise 403). A SubscriptionConfirmation is finished automatically by issuing a GET to SubscribeURL. If the server has no topic ARN, 501. Client libraries do not call it.

operationId sesHook

Request body: text/plain · string

StatusDescriptionResponse body
200Received (an unknown event type or an unknown id also returns 200)
400
403The SNS signature does not match
501The webhook is off

GET /v1/orgs/{orgSlug}/projects/{projectName}/email

Whether enabled, the address, the sender, the hourly limit, and recent send/receive counts (docs/email.md §5). address and from are filled in even when not enabled — they are the material for "this is the address you would get". granted is the real state.

Requires viewer or above.

operationId getEmail

StatusDescriptionResponse body
200Email statusEmailStatus
403
404
503no_coreError

POST /v1/orgs/{orgSlug}/projects/{projectName}/email

Idempotent. There is no request body — the address is ours to decide (<project>.<org>.<mail-domain>) and the limit comes from the plan. The address is fixed at the names in effect when it was granted.

Once enabled, the node wires env.email at the next convergence and mail sent to the address reaches the worker's email(). Sending and receiving are enabled together — one domain is the name for both directions.

member or above. Audit email.grant.

operationId grantEmail

StatusDescriptionResponse body
200Grant status (the existing values if it already existed)EmailStatus
403
404
409email_unavailable — this deployment has no mail domain. email_address_taken — another project holds the same addressError
503no_coreError

DELETE /v1/orgs/{orgSlug}/projects/{projectName}/email

Mail to the address is now 550 — the sending MTA gets a bounce and does not retry. Idempotent.

admin or above. Audit email.revoke.

operationId revokeEmail

StatusDescriptionResponse body
204Disabled
403
404
503no_coreError

GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log

One row per message sent and received, newest first (docs/email.md §6.1). Envelope, outcome, size and SPF result. The raw message is at …/log/{mailId}/raw.

Retention is the plan's current value — 30 days on free, 365 days on pro (keepDays).

Requires viewer or above.

operationId listMailLog

ParameterInRequiredTypeDescription
directionqueryNostringBoth when empty
cursorqueryNostringThe cursor from the previous page
limitqueryNointeger
StatusDescriptionResponse body
200One pageMailLogPage
403
404

GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}

An id outside the project is a 404 — you cannot feel around another project's log by id. Requires viewer or above.

operationId getMailLog

StatusDescriptionResponse body
200One messageMailLogEntry
403
404

GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}/raw

The raw message as it is, headers included. Received mail includes the Received and Authentication-Results headers we added; sent mail is assembled from what was handed to the relay. It downloads as .eml. A row with no raw message (hasRaw: false) is a 404. Requires viewer or above.

operationId getMailLogRaw

StatusDescriptionResponse body
200Raw messagestring
403
404

On this page