MakiSend API reference: send email, templates and logs
POST /send-email and the email endpoints of a self-hosted MakiSend instance: authentication, inline or template payloads, attachments, responses and logs.
Base URL: your own instance, https://your-instance.workers.dev. Authenticate withAuthorization: Bearer <api-key> or x-api-key. The full document is at/openapi.json.
POST /send-email· Queue a transactional emailGET /email-logs· List email logsGET /email-logs/{id}· Get an email logGET /templates· List templatesPOST /templates· Create a templateGET /templates/{id}· Get a templatePUT /templates/{id}· Update a templateDELETE /templates/{id}· Delete a templatePOST /templates/{id}/preview· Preview a template
This page in Markdown: /api.md.
POST /send-email
Queue a transactional email. Accepts either inline content (subject, text, html) or a templateId plus variables. The two shapes are mutually exclusive. HTML is sanitized before delivery. Send the optional Idempotency-Key header to make retries safe.
Auth: API key: Authorization: Bearer <api-key> or x-api-key: <api-key>.
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
Idempotency-Key | header, string | no | 1 to 255 characters. Optional unique key for safe retries. Replaying the same key and body returns the stored response for 24 hours; reusing it with a different body returns 409 |
Request body
Inline email content, or a template reference. The shapes are mutually exclusive.
Inline content
| Field | Type | Required | Notes |
|---|---|---|---|
to | string (email) | yes | At most 320 characters |
subject | string | yes | 3 to 500 characters |
text | string | yes | 10 to 20000 characters |
html | string | yes | 1 to 100000 characters |
attachments | array of object | no | At most 5 items. Each item: filename, content, content_type (optional) |
From a saved template
| Field | Type | Required | Notes |
|---|---|---|---|
to | string (email) | yes | At most 320 characters |
templateId | string | yes | 1 to 128 characters |
variables | object | no | Values: string | number | boolean |
attachments | array of object | no | At most 5 items. Each item: filename, content, content_type (optional) |
Responses
202: Email persisted and queued for asynchronous delivery.400: Request validation failed.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.404: The referenced template does not exist for this account.409: Idempotency key conflict.429: Only when the instance setsSEND_RATE_LIMIT: this API key reached its send quota.Retry-Aftergives the seconds until the window restarts.500: Unexpected server error.
GET /email-logs
List email logs. Newest first, cursor-paginated. The recipient filter is applied to the decrypted current page, so a page can contain fewer rows than limit when filtering by to.
Auth: Dashboard session (sign in to your instance first).
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
smtpConfigId | query, string | no | At most 128 characters. The emails sent with this configuration's keys, plus its test sends |
apiKeyId | query, string | no | At most 128 characters. Only the emails sent with this API key |
to | query, string | no | At most 320 characters. Case-insensitive substring match on the decrypted recipient |
status | query, string | no | One of received, processing, cleaned, sent, failed |
limit | query, integer | no | 1 to 100. Default 50 |
cursor | query, string | no | At most 512 characters. Opaque nextCursor from the previous page |
Responses
200: Page of email logs with their history.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.500: Unexpected server error.
GET /email-logs/{id}
Get an email log.
Auth: Dashboard session (sign in to your instance first).
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
id | path, string | yes | 1 to 128 characters. Resource identifier |
Responses
200: Email log with its full history.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.404: Resource not found.500: Unexpected server error.
GET /templates
List templates.
Auth: Dashboard session (sign in to your instance first).
Responses
200: Templates owned by the session user.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.500: Unexpected server error.
POST /templates
Create a template. Use {{variable}} placeholders in the subject, HTML, or text. Variables are supplied at send time.
Auth: Dashboard session (sign in to your instance first).
Request body
New reusable email template.
JSON body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | 1 to 100 characters |
subject | string | yes | 1 to 500 characters |
format | string | no | One of legacy, react-email, react-email-code. Default legacy |
editorJson | string | no | 2 to 250000 characters |
source | string | no | 1 to 100000 characters |
html | string | yes | 1 to 100000 characters |
text | string | yes | 1 to 20000 characters |
Responses
201: Template created.400: Request validation failed.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.500: Unexpected server error.
GET /templates/{id}
Get a template.
Auth: Dashboard session (sign in to your instance first).
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
id | path, string | yes | 1 to 128 characters. Resource identifier |
Responses
200: Template.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.404: Resource not found.500: Unexpected server error.
PUT /templates/{id}
Update a template.
Auth: Dashboard session (sign in to your instance first).
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
id | path, string | yes | 1 to 128 characters. Resource identifier |
Request body
Partial template update.
JSON body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | no | 1 to 100 characters |
subject | string | no | 1 to 500 characters |
format | string | no | One of legacy, react-email, react-email-code |
editorJson | object | no | |
source | object | no | |
html | string | no | 1 to 100000 characters |
text | string | no | 1 to 20000 characters |
Responses
200: Template updated.400: Request validation failed.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.404: Resource not found.500: Unexpected server error.
DELETE /templates/{id}
Delete a template.
Auth: Dashboard session (sign in to your instance first).
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
id | path, string | yes | 1 to 128 characters. Resource identifier |
Responses
200: Template deleted.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.404: Resource not found.500: Unexpected server error.
POST /templates/{id}/preview
Preview a template. Renders the saved subject, HTML, and text with the supplied variables. Missing variables, line breaks, and length limits are reported exactly as they would be by POST /send-email.
Auth: Dashboard session (sign in to your instance first).
Parameters
| Name | In, type | Required | Notes |
|---|---|---|---|
id | path, string | yes | 1 to 128 characters. Resource identifier |
Request body
Variable values used to render a saved template preview.
JSON body
| Field | Type | Required | Notes |
|---|---|---|---|
variables | object | no | Values: string | number | boolean |
Responses
200: Rendered template preview.400: Request validation failed.401: Missing or invalid credentials.403: Credentials are valid but the resource is not accessible.404: Resource not found.500: Unexpected server error.