haru Mail ドキュメント

haru Mail は、日本のAI開発者のためのメール送受信APIです。独自ドメインからのトランザクションメール送信と、独自ドメインでのメール受信を、REST API・MCP・CLIの3つの入口から使えます。DNS設定(SPF / DKIM / DMARC)はすべてこちらで用意するので、渡されたAPIキーだけで今日から送れます。

REST API

Resendに近い書き味のJSON API。curl一発で送信。

MCP

Claude・Cursor等のAIエージェントから直接メールを送受信。

CLI

npx harumail send でターミナルから。CI/CDにも。

ベースURL: https://harumail.app(正式ドメインは後日切替予定。切替後も旧URLは動作します)

クイックスタート

APIキー(hm_ で始まる文字列)はオンボーディング時にお渡ししています。まず1通送ってみます。

curl -X POST https://harumail.app/v1/emails \
  -H "Authorization: Bearer hm_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "お店の名前 <info@example.com>",
    "to": "customer@example.jp",
    "subject": "ご予約ありがとうございます",
    "text": "このたびはご予約ありがとうございます。"
  }'
const res = await fetch("https://harumail.app/v1/emails", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.HARUMAIL_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from: "お店の名前 ",
    to: "customer@example.jp",
    subject: "ご予約ありがとうございます",
    text: "このたびはご予約ありがとうございます。",
  }),
});
const { id } = await res.json(); // em_xxxx
import os, requests

res = requests.post(
    "https://harumail.app/v1/emails",
    headers={"Authorization": f"Bearer {os.environ['HARUMAIL_API_KEY']}"},
    json={
        "from": "お店の名前 ",
        "to": "customer@example.jp",
        "subject": "ご予約ありがとうございます",
        "text": "このたびはご予約ありがとうございます。",
    },
)
print(res.json())  # {"id": "em_xxxx", ...}

成功すると {"id": "em_...", "status": "sent", ...} が返ります。届いたかどうかは送信履歴やダッシュボードでいつでも確認できます。

認証(APIキー)

すべてのAPIは Authorization: Bearer hm_... ヘッダーで認証します。キーはアカウント(テナント)単位で発行され、そのアカウントに登録された差出人ドメインからしか送信できません。キーが漏れても他社のドメインからは1通も送れない設計です。

APIキーはサーバーサイドで使ってください。ブラウザのコードに埋め込むと第三者に読まれます。キーの再発行・失効はサポートまで(即時対応します)。

レート制限: 120リクエスト/分(キー単位)。超えると 429 が返るので、少し待って再試行してください。

メールを1通送信します。

フィールド必須説明
fromstring必須差出人。"info@example.com" または "表示名 <info@example.com>"。登録済みドメインのアドレスに限る
tostring | string[]必須宛先。to/cc/bcc合計50件まで
subjectstring必須件名
textstringテキスト本文(htmlとどちらか必須)
htmlstringHTML本文。textとの併記推奨(届きやすさが上がります)
reply_tostring任意返信先アドレス
cc / bccstring | string[]任意CC / BCC
headersobject任意カスタムヘッダー(文字列→文字列)
attachmentsarray任意{filename, content(base64), content_type, disposition?, content_id?} の配列。32個まで・メール全体で5MiBまで
// レスポンス(200)
{
  "id": "em_1a2b3c4d5e6f7a8b9c0d",
  "status": "sent",
  "from": "お店の名前 <info@example.com>",
  "to": ["customer@example.jp"],
  "subject": "ご予約ありがとうございます",
  "message_id": "...",
  "created_at": "2026-08-06 12:34:56"
}

添付ファイルの例

{
  "from": "info@example.com",
  "to": "customer@example.jp",
  "subject": "請求書をお送りします",
  "text": "請求書を添付いたします。",
  "attachments": [
    { "filename": "invoice.pdf", "content": "JVBERi0xLjQK...", "content_type": "application/pdf" }
  ]
}
POST/v1/emails/batch

一斉送信(メルマガ・お知らせ配信)。{"emails": [送信オブジェクト, ...]} の形式で1リクエスト最大50通。各通は独立に検証・送信・記録され、宛先ごとに本文を変えられます。結果は通ごとに返り、月間上限に達した時点で残りは送信されず明示されます。

{
  "emails": [
    { "from": "news@example.com", "to": "a@example.jp", "subject": "8月のお知らせ", "text": "A様 ..." },
    { "from": "news@example.com", "to": "b@example.jp", "subject": "8月のお知らせ", "text": "B様 ..." }
  ]
}
// レスポンス: { "data": [{index, id, status} | {index, error}], "sent": 2, "failed": 0 }
広告・宣伝を含む配信は、受信に同意した相手(オプトイン)にのみ送ってください(特定電子メール法)。同意のない広告メールの送信は利用規約で禁止しています。
POST/v1/emails/bulk

大量配信・予約送信・ステップメールのためのキュー投入。1リクエスト最大1,000通を受け付け、毎分100通ずつの安全な速度で自動配信します(ISPに嫌われにくいドリップ方式)。scheduled_atで日時指定("2026-08-10 09:00"は日本時間として解釈・各通ごとの個別指定も可)。

{
  "emails": [ { "from": "...", "to": "...", "subject": "...", "text": "..." }, ... ],
  "scheduled_at": "2026-08-10 09:00"
}
// レスポンス: { "batch_id": "bk_...", "queued": 1000, "scheduled_from": "..." }

進捗は GET /v1/bulk/:batch_id(queued/sent/failed件数・失敗理由・次回送信時刻)、未送信分の取り消しは DELETE /v1/bulk/:batch_idステップメールは、同じ宛先リストへ scheduled_at を「登録日・3日後・7日後」とずらして複数回投入するだけで組めます。

GET/v1/emails

送信履歴を新しい順に返します(本文なしの要約)。クエリ: limit(1–100・既定20)、statussent / failed)。

curl -H "Authorization: Bearer hm_..." \
  "https://harumail.app/v1/emails?limit=10&status=failed"
GET/v1/emails/:id

送信メール1件の詳細を返します。本文(text / html)・エラー内容・添付のメタ情報を含みます。失敗調査はまずここを見てください。

冪等性(二重送信防止)

Idempotency-Key ヘッダーを付けると、同じキーでの再送信は実際には送信せず初回の結果をそのまま返します。リトライ処理やAIエージェントからの送信で二重送信を防げます。キーは注文IDなど自然な一意値を推奨(256文字まで・テナント内で一意)。

curl -X POST .../v1/emails \
  -H "Authorization: Bearer hm_..." \
  -H "Idempotency-Key: order-20260806-0012" \
  -d '{ ... }'
GET/v1/inbound

受信メールを新しい順に返します(要約)。GET /v1/inbound/:id で本文・ヘッダーを含む詳細が取れます。受信メールは90日間保持されます。

受信を使うには、対象ドメインの受信設定(MXレコード)をこちらで行います。オンボーディング時に「受信も使う」と伝えてください。既存のメール受信(Google Workspace等)と共存させる設計もご相談ください。

受信Webhook

メールを受信した瞬間に、登録されたURLへ通知をPOSTします(設定はサポートまで)。ペイロード:

{
  "type": "inbound.received",
  "data": { "id": "in_...", "from": "...", "to": "...", "subject": "...", "created_at": "..." }
}

本文は含まれないため、GET /v1/inbound/:id で取得してください。リクエストには署名ヘッダーが付きます:

x-harumail-signature: sha256=<HMAC-SHA256 hex>

// 検証(Node)
import { createHmac, timingSafeEqual } from "node:crypto";
const expected = "sha256=" + createHmac("sha256", WEBHOOK_SECRET).update(rawBody).digest("hex");
const valid = timingSafeEqual(Buffer.from(expected), Buffer.from(header));

配信停止(ワンクリックunsubscribe)と抑制リスト

送信時に "unsubscribe": true を付けると(メルマガ・お知らせ・広告はこれを付けてください):

  • Gmailなどが対応するワンクリック配信停止ヘッダー(RFC 8058・Gmailの大量送信者要件)と、本文末尾の配信停止リンクを自動付与
  • 停止した宛先は自動で抑制リストに入り、以後の unsubscribe: true 送信からは自動除外(422で明示)
  • 取引メール(注文確認等・unsubscribeなしの送信)は止まりません(意図的な設計)

リストの確認・手動追加・解除: GET/POST /v1/suppressionsDELETE /v1/suppressions/:email

開封・クリック計測と統計

"track": true を付けたHTMLメールは開封(ピクセル)とクリック(署名付きリダイレクト・改ざん不可)を計測します。GET /v1/stats で直近30日の送信・失敗・受信・開封・クリック・開封率・配信停止数を取得。大量配信は GET /v1/bulk/:id にも開封・クリック数が出ます。

フェイルオーバー配信(Business以上)

メールは「配信網」(送信インフラ)を通って届きますが、どの配信網もまれに障害を起こします。haru Mailは別会社の予備配信網を常時スタンバイし、主経路の障害・一時的なレート制限を検知すると、その1通から自動で予備網に切り替えて届け続けます。

  • お客様の設定・コード変更は一切不要(サービスの裏側で自動)
  • 差出人の認証設定(SPF/DKIM)は両方の網に対して当社が維持します
  • どちらの網で届いたかは送信履歴の provider/v1/statssent_via_failover に記録=「保険が働いた回数」まで見えます
  • 設定ミス起因のエラー(差出人未検証等)は切替対象外(切り替えても届かないため)
1社の配信基盤だけに依存しない「マルチプロバイダ配信」は、Resend・SendGrid等の単一基盤サービスにはない設計です。BusinessまたはProプランで自動的に有効になります。
GET/v1/domains

このAPIキーで差出人に使えるドメインの一覧を返します。ドメインの追加はサポートまで(SPF / DKIM / DMARC の設定込みでこちらが対応します。お客様側のDNS作業は原則不要です)。

GET/v1/usage
{ "month": "2026-08", "sent": 128, "failed": 2, "limit": 3000, "remaining": 2872 }

月間上限に達すると送信APIは 402 を返します(それまでの送信は影響を受けません)。上限の引き上げはプラン変更で対応します。

エラー

エラーはすべて {"error": "日本語の説明"} の形で返ります。

HTTP意味
400JSONの形式が不正
401APIキーが無効・失効
402月間送信上限に到達
403登録されていないドメインからの送信
404対象が見つからない
422フィールドの内容が不正(メッセージに具体的な理由)
429レート制限(120回/分)
502配信基盤側のエラー(メッセージに詳細。送信は記録され status: failed で履歴に残る)

MCPサーバー

haru Mail はMCP(Model Context Protocol)サーバーを標準提供しています。Claude等のAIエージェントに登録すると、AIが直接メールを送受信できるようになります。認証はREST APIと同じキーです。

claude mcp add --transport http harumail \
  https://harumail.app/mcp \
  --header "Authorization: Bearer hm_xxxxxxxxxxxxxxxx"

登録後はAIに「予約確認メールをcustomer@example.jpに送って」と話すだけです。Cursor・その他のStreamable HTTP対応クライアントでも同じURLで使えます。

MCPツール一覧

ツールできること
send_email下書き作成(この時点では送信されない)
send_batch_emails / send_bulk_emails複数・大量配信の下書き作成(〜50通 / 〜1,000通・予約・ステップメール)
confirm_send下書きの送信確定(あなたが「送信して」と明確に指示した時だけAIが呼べる)
discard_draft下書きの破棄(24時間確定されない下書きは自動破棄)
get_bulk_status / cancel_bulk大量配信の進捗確認・未送信分の取り消し
list_emails / get_email送信履歴・詳細(エラー調査)
list_inbound / get_inbound受信メールの一覧・本文取得
list_domains差出人に使えるドメインの確認
get_usage今月の送信数・残数
安全設計: AI経由の送信は必ず「下書き→あなたの確認→送信確定」の二段階です。AIが勝手にメールを送ることは構造的にできません(送信確定は専用ツールに分離されており、確認なしの呼び出しを禁止しています。確定されない下書きは24時間で自動破棄)。加えて、送信できるのは登録済みドメインからだけ・月間上限とレート制限もRESTと共通で効きます。

CLI

npx harumail login hm_xxxxxxxxxxxxxxxx

npx harumail send --to customer@example.jp --subject "件名" --text "本文"
npx harumail logs            # 送信履歴
npx harumail inbound         # 受信メール
npx harumail usage           # 今月の使用量

本文をパイプで渡すこともできます: cat body.txt | npx harumail send --to ... --subject ... --text -

AIエージェント連携

AIにharu Mailを組み込ませる場合は、仕様全文を1ファイルにまとめた llms-full.txt をAIに渡してください。「このAPIでメール送信を実装して」だけで統合できます。llms.txt(索引)にも対応しています。

ドメインお預かり(ネームサーバー変更)の安全手順

独自ドメインで送るには、ドメインのDNS管理をこちらでお預かりします(お名前.com等の契約はそのまま・ドメイン移管ではありません。作業はネームサーバー欄の書き換え1回だけ)。「NS変更でサイトやメールが壊れないか」への答えを、隠さず全部書きます。

正直なリスク開示

DNSの仕様上、外部から全レコードを完全に列挙する方法は存在しません。つまりこちらが把握できなかった設定(申告されていないサブドメインや外部サービスの検証レコード等)は移行時に漏れる可能性がゼロではありません。リスクの正体はこれ1つで、以下の手順はすべてこれを潰すためにあります。

こちらがやること(4段階)

  1. 全量調査 — 証明書ログ(crt.sh)による隠れサブドメインの列挙+定番レコードの機械チェック+利用サービスのヒアリング
  2. 差分ゼロの証明 — 新旧のDNSに同じ質問を投げて全件照合し、差分ゼロのレポートをお渡しして、確認・承諾をいただいてから切替します
  3. 切替後の監視 — 24〜48時間、同じ照合を自動で回して監視します
  4. 即時ロールバック — 元のDNS設定は消えないため、ネームサーバーを書き戻すだけで切替前の状態に完全復帰できます

お客様にお願いすること

利用中のサービス(メール・サイト・予約システム・社内ツール等)の申告です。申告いただけなかった設定に起因する障害は責任範囲外となります(利用規約 第5条)。不安な場合は、NS変更なしで使えるtrial差出人(下記FAQ)から始めてください。

よくある質問

ドメイン設定が終わる前に試せますか?

試せます。アカウント発行時に t-xxxxxx@(共有ドメイン) 形式のtrial差出人をお渡しします。DNS設定もNS変更も一切不要で、その場からAPI・MCP・CLIの送信を試せます。独自ドメインに切り替えるときも、コードの変更は from を書き換えるだけです。

迷惑メールに入りませんか?

送信ドメインごとにSPF / DKIM / DMARCを正しく設定した上で送信します(設定はこちらが代行)。DKIM署名は差出人ドメインと一致(アライメント)するため、GmailのDMARCポリシー要件を満たします。

Google Workspace(Gmail)でメールを使っていますが併用できますか?

できます。haru Mailの送信設定はサブドメイン(cf-bounce.あなたのドメイン)だけを使うため、普段のメール受信(MXレコード)や送信には一切触れません。Google Workspaceでの送受信はそのまま、同じドメインからAPIメールも送れるようになります。実際にGoogle Workspace運用中のドメインで検証済みです。

Resendとの違いは?

書き味はほぼ同じで、日本語ドキュメント・日本語エラーメッセージ・DNS設定の代行・受信込み、の点が異なります。既存のResend実装からの移行は、エンドポイントとキーの差し替えでほぼ完了します。

SMTPは使えますか?

現在はREST / MCP / CLIのみです。SMTP接続が必要な場合はご相談ください。

送信上限を超えたら?

402 が返り、それ以上は送信されません。超過課金は一切発生しません(上限に達したら止まるだけ。90%/100%時点で通知します)。プラン変更で即日引き上げできます。

料金は?

Free ¥0(3,000通/月・2ドメイン・期限なし)/ Standard ¥1,480(10,000通)/ Business ¥2,680(50,000通・請求書払い可)/ Pro ¥4,480(100,000通)。全プランに受信・Webhook・MCP・CLI・DNS設定代行が含まれます。AI向けの料金表は /pricing.md

個人・フリーランスでも使えますか?

使えます(事業でのご利用が対象です。法人限定の制約はありません)。請求書払いが必要な場合はBusinessプラン以上で対応します。

変更履歴

日付内容
2026-08-06初版公開(送信 / 受信 / MCP / CLI / 冪等性 / Webhook)