runlot
ReferenceAPI

email

Covers 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}/emailTurns on email (a deployment calls this after reading "email": true)
DELETE/v1/orgs/{orgSlug}/projects/{projectName}/emailTurns off email (runlot email delete)
GET/v1/orgs/{orgSlug}/projects/{projectName}/email/logEmail log (runlot email log)
GET/v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}Metadata for one email
GET/v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}/rawRaw email message (message/rfc822)

POST /v1/hooks/ses

This is not a path users call. Amazon SNS delivers SES events here via an HTTPS subscription. Authentication is not a token but an SNS signature — it accepts the request 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). SubscriptionConfirmation completes automatically by sending a GET to SubscribeURL. Returns 501 if the server has no topic ARN. Client libraries do not call this.

operationId sesHook

Request body: text/plain · string

Status codeDescriptionResponse body
200received (unknown event types and unknown ids also return 200)
400
403the SNS signature does not match
501the webhook is off

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

Whether granted, address, sender, hourly cap, recent sent/received counts (docs/email.md §5). Even without a grant, address and from come populated — they are the material for "here's what the address would be if you turn this on." granted is the real state.

viewer or above.

operationId getEmail

Status codeDescriptionResponse body
200Email statusEmailStatus
403
404
503no_coreError

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

Is idempotent. There is no request body — we determine the address (<project>.<org>.<mail-domain>), and the plan determines the limit. The address is fixed to the name at the time of grant.

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

Requires member or higher. Audited as email.grant.

operationId grantEmail

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

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

Mail sent to that address now gets 550 — the sending MTA receives a bounce and does not retry. This is idempotent.

Requires admin or higher. Audit event email.revoke.

operationId revokeEmail

Status codeDescriptionResponse body
204turned off
403
404
503no_coreError

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

One line per sent and received message, in reverse chronological order (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 higher.

operationId listMailLog

ParameterLocationRequiredTypeDescription
directionqueryNostringBoth, if empty
cursorqueryNostringThe cursor from the previous page
limitqueryNointeger
Status codeDescriptionResponse body
200One pageMailLogPage
403
404

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

An id outside the project returns 404 — you cannot probe another project's logs by id. Viewer or above.

operationId getMailLog

Status codeDescriptionResponse body
200One emailMailLogEntry
403
404

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

The raw message as-is, including headers. For received mail, this includes the Received and Authentication-Results headers we added; for sent mail, it is assembled from what was handed to the relay. Downloads as .eml. Rows with no raw message (hasRaw: false) return 404. viewer or above.

operationId getMailLogRaw

Status codeDescriptionResponse body
200Original textstring
403
404

On this page