POST /v1/convert
This is the main endpoint of the API. It converts your Markdown input into a fully-rendered HTML email, ready to be sent.
Subscription Requirements
- Basic conversion (Markdown to HTML): Available with active subscription
- Custom Templates (
template_id): Available with active subscription - AI Orchestration (
ai_service): Available with active subscription (BYOK required)
Rate Limits
All users with an active subscription have a unified rate limit of 5 requests/second (~18,000 requests/hour).
When you exceed your rate limit, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait before retrying.
Pricing
- $1/month subscription includes 1,000 API calls
- Pay-As-You-Go for additional calls beyond the included amount
Headers
You must authenticate by providing your API key in the X-Typemail-Key header.
X-Typemail-Key: <YOUR_API_KEY>
Content-Type: application/json
Request Body
The request body should be a JSON object with the following parameters:
| Name | Type | Required | Description |
|---|---|---|---|
markdown | string | yes | Markdown content to convert into HTML. If ai_service is used, the AI-generated text replaces {ai_content} inside your markdown. |
template_id | string | no | Template UUID (from your Dashboard → Templates). When provided, applies your custom CSS. |
ai_service | object | no | AI orchestration parameters. Requires Pro/Business and a stored BYOK key for the provider unless you pass api_key inline. |
ai_service fields:
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | One of: openai, anthropic, gemini. |
model | string | yes | The model name for the provider (e.g. gpt-4o, claude-3-sonnet, gemini-1.5-pro). |
prompt | string | yes | The user prompt to generate content. |
api_key | string | no | Inline provider API key. If omitted, the server will use your stored BYOK for the given provider. |
max_tokens | number | no | Max tokens for the generation (provider dependent). |
temperature | number | no | Sampling temperature. |
system | string | no | Optional system prompt (where supported). |
Example Request (cURL)
curl -X POST https://www.typemail.me/api/v1/convert \
-H "X-Typemail-Key: $TYPEMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Hello, world!\nThis is **Typemail**.\n\nGenerated: {ai_content}",
"template_id": "<YOUR_TEMPLATE_UUID>",
"ai_service": {
"provider": "openai",
"model": "gpt-4o",
"prompt": "Write a short greeting for our newsletter",
"max_tokens": 200,
"temperature": 0.7
}
}'
Batch Conversion
You can convert multiple markdowns in a single request by providing an items array:
curl -X POST https://www.typemail.me/api/v1/convert \
-H "X-Typemail-Key: $TYPEMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"markdown": "# Email 1\nFirst email content",
"template_id": "<TEMPLATE_UUID>"
},
{
"markdown": "# Email 2\nSecond email content"
}
]
}'
Response:
{
"results": [
{ "html": "<h1>Email 1</h1>...", "error": null },
{ "html": "<h1>Email 2</h1>...", "error": null }
],
"count": 2
}
Example Request (JavaScript)
const res = await fetch('https://www.typemail.me/api/v1/convert', {
method: 'POST',
headers: {
'X-Typemail-Key': process.env.TYPEMAIL_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
markdown: '# Hello, world!\nThis is **Typemail**.\n\nGenerated: {ai_content}',
template_id: '<YOUR_TEMPLATE_UUID>',
ai_service: {
provider: 'openai',
model: 'gpt-4o',
prompt: 'Write a short greeting for our newsletter',
max_tokens: 200,
temperature: 0.7
}
})
});
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
// data.html -> fully-rendered HTML email