Skip to content
Rasel MailHelp center
Categories and guides
For developers

Send your first website email

Prepare a domain and project, then try cURL, JavaScript, Python or PHP.

Editorial update: October 30, 2026
In this guide

Prepare a sending project

  1. Activate a paid plan, add a custom domain and finish its sending records.
  2. Open Control Panel → Applications → Website email. Request a sending pack and track manual payment confirmation.
  3. Create a project and choose its domain. Copy the once-visible key into your server’s secret store.
  4. Replace example addresses with your own test addresses. The from address must belong to the project’s domain.

Try cURL

Send a test message
curl -i 'https://raselmail.com/api/v1/delivery/messages'   -H "Authorization: Bearer $RASEL_API_KEY"   -H 'Idempotency-Key: order-123-confirmation'   -H 'Content-Type: application/json'   --data '{"from":"no-reply@example.com","to":["customer@example.net"],"subject":"Order received","text":"We received your order.","html":"<p>We received your order.</p>"}'

Server-side examples

JavaScript / Node.js
const key = process.env.RASEL_API_KEY;
if (!key) throw new Error('Missing RASEL_API_KEY');
const response = await fetch('https://raselmail.com/api/v1/delivery/messages', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + key,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'order-123-confirmation',
  },
  body: JSON.stringify({"from":"no-reply@example.com","to":["customer@example.net"],"subject":"Order received","text":"We received your order.","html":"<p>We received your order.</p>"}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || 'Send request failed');
console.log(result.id, result.state);
Python — standard library
import json, os, urllib.request, urllib.error

payload = {"from":"no-reply@example.com","to":["customer@example.net"],"subject":"Order received","text":"We received your order.","html":"<p>We received your order.</p>"}
request = urllib.request.Request(
    'https://raselmail.com/api/v1/delivery/messages',
    data=json.dumps(payload).encode('utf-8'),
    headers={
        'Authorization': 'Bearer ' + os.environ['RASEL_API_KEY'],
        'Content-Type': 'application/json',
        'Idempotency-Key': 'order-123-confirmation',
    }, method='POST')
try:
    with urllib.request.urlopen(request, timeout=20) as response:
        result = json.load(response)
        print(result['id'], result['state'])
except urllib.error.HTTPError as error:
    print(error.code, error.read().decode('utf-8'))
    raise
PHP — using cURL
<?php
$key = getenv('RASEL_API_KEY');
if (!$key) { throw new RuntimeException('Missing RASEL_API_KEY'); }
$request = curl_init('https://raselmail.com/api/v1/delivery/messages');
curl_setopt_array($request, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 20,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $key,
    'Content-Type: application/json',
    'Idempotency-Key: order-123-confirmation',
  ],
  CURLOPT_POSTFIELDS => '{"from":"no-reply@example.com","to":["customer@example.net"],"subject":"Order received","text":"We received your order.","html":"<p>We received your order.</p>"}',
]);
$body = curl_exec($request);
if ($body === false) { throw new RuntimeException(curl_error($request)); }
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
curl_close($request);
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300) {
  throw new RuntimeException($result['error'] ?? 'Send request failed');
}
echo $result['id'];

What happens after the response?

Example HTTP 202 response
{"id":"11111111-1111-4111-8111-111111111111","state":"queued","recipient_count":1}

Store the ID with your business event and poll its status. queued means the request was recorded; accepted means the sending provider acknowledged it, not confirmed Inbox delivery. Do not log keys or password-reset links.