If you prefer not to use an SDK, you can call the Maildeno Render API directly over HTTP.

Base URL

https://api.maildeno.com

Authentication

All requests require a Bearer token in the Authorization header:

Authorization: Bearer sk_live_your_api_key

Endpoints

GET /v1/sdk/template/{id}

Fetch a template’s JSON definition and render it locally using the SDK’s local render engine — an embedded Wasm module for the JS/Python SDKs, a bundled native binary for the PHP SDK. Merge tags and context never leave your server.

Request

GET /v1/sdk/template/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <API_KEY>

Response — 200 OK

Returns the template’s JSON definition — the TemplateJson payload the SDKs cache and render locally via their respective engines. Treat the body as opaque unless you are building your own renderer against the exported TemplateJson type.

Error responses

Same code values as the render endpoint: 401 INVALID_API_KEY, 403 FORBIDDEN, 404 TEMPLATE_NOT_FOUND. See Error Codes.

POST /v1/sdk/render

This endpoint is deprecated. The official SDKs no longer call it — they fetch template JSON via GET /v1/sdk/template/{id} and render in-process using the WASM engine, so dynamic data never leaves your server. The endpoint still works for existing direct-HTTP integrations until it is removed; check the Deprecation response header for the sunset date. New integrations should use GET /v1/sdk/template/{id} with an SDK instead.

Render a template server-side and return the output string. The request body’s dynamic_data is sent to and processed by the Maildeno server.

Request

POST /v1/sdk/render
Content-Type: application/json
Authorization: Bearer <API_KEY>
{
  "template_id": "550e8400-e29b-41d4-a716-446655440000",
  "target": "html",
  "dynamic_data": {
    "merge_tags": {
      "text": {
        "name": "Noruwa",
        "company": "Maildeno"
      },
      "url": {
        "reset_url": "https://app.example.com/reset/abc123"
      },
      "attr": {
        "alt_text": "Banner image"
      }
    },
    "context": {
      "plan": "pro",
      "country": "usa"
    }
  }
}

Request fields

Field Type Required Description

template_id

string (UUID v4)

The template to render.

target

string

"html" (default), "react-email", or "mjml".

dynamic_data

object

See below.

dynamic_data.merge_tags

object

{ text?, url?, attr? } — all optional sub-objects.

dynamic_data.context

object

Flat map of string | number | boolean values.

Response — 200 OK

The response body is the raw rendered string (not JSON-wrapped):

<!DOCTYPE html>
<html lang="en">
...
</html>

Content-Type is text/html for html target, text/plain for react-email and mjml.

Error responses

Status Code Description

401

INVALID_API_KEY

Missing, malformed, revoked, or expired key.

403

FORBIDDEN

Key does not have scope for the requested target.

404

TEMPLATE_NOT_FOUND

Template ID does not exist.

422

RENDER_ERROR

Request body is invalid or render pipeline failed. Includes issues array.

{
  "code": "RENDER_ERROR",
  "message": "template_id is not a valid UUID",
  "issues": [
    {
      "loc": ["body", "template_id"],
      "msg": "Input should be a valid UUID, invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `n` at 1",
      "type": "uuid_parsing"
    }
  ]
}

curl examples

# Fetch template JSON for local rendering
curl https://api.maildeno.com/v1/sdk/template/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer $MAILDENO_API_KEY"
# Deprecated — render server-side (minimal)
curl -X POST https://api.maildeno.com/v1/sdk/render \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MAILDENO_API_KEY" \
  -d '{"template_id": "550e8400-e29b-41d4-a716-446655440000"}'
# Deprecated — render server-side (full request with merge tags and context)
curl -X POST https://api.maildeno.com/v1/sdk/render \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MAILDENO_API_KEY" \
  -d '{
    "template_id": "550e8400-e29b-41d4-a716-446655440000",
    "target": "html",
    "dynamic_data": {
      "merge_tags": {
        "text": { "name": "Noruwa", "company": "Maildeno" }
      },
      "context": { "plan": "pro" }
    }
  }'

Key management endpoints

POST /api/v1/keys

Create a new API key.

curl -X POST https://api.maildeno.com/api/v1/keys \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <ADMIN_KEY>" \
  -d '{"name": "Production HTML", "targets": ["html"]}'
{
  "id": "key_01abc...",
  "name": "Production HTML",
  "key": "sk_live_...",   // shown once — copy it now
  "targets": ["html"],
  "created_at": "2025-01-01T00:00:00Z"
}