SMTP と HTTP API
API キーを作成し、SMTP または HTTP API でメールを送信します。リクエストフィールド、レスポンス、エラーコード、例を掲載しています。
ストリームからの送信方法は 2 つあります。任意のアプリケーションやメールライブラリから SMTP で送信する方法と、HTTP API で送信する方法です。どちらも同じ API キー、クォータ、抑制リスト、イベントを使用します。始める前に、送信ドメインを検証し、API キーを作成してください。
API キー
- ストリームを開き、API キータブに移動します。
- キーを作成をクリックし、
productionなどの 名前を入力して確定します。 - 表示されたキーをコピーし、保存しましたをクリックします。キーが表示されるのはこのときだけです。以降、一覧には
ytm_aB3dE6gH…のような プレフィックスのみが表示されます。
キーはすべて ytm_ で始まります。1 つのストリームで有効なキーは最大 20 個です。一覧には各キーの最終使用日時が表示されます。キーを廃止するには 失効をクリックします。そのキーを使っているプログラムは直ちに動作しなくなります。キーは所属するストリームでのみ機能します。
API キーはサーバー上で保管してください。ブラウザのコード、モバイルアプリ、公開リポジトリには含めないでください。キーを持っている人は誰でも、お客様のドメインとしてメールを送信できます。
SMTP
ストリームの 概要タブに SMTP の設定が表示されます。
| 設定 | 値 |
|---|---|
| ホスト | ストリームに表示される SMTP ホスト。通常は smtp.tm.yeapcloud.net |
| ポート | STARTTLS の場合は 587、TLS の場合は 465 |
| ユーザー名 | apikey(この語をそのまま入力) |
| パスワード | このストリームの API キー |
| カテゴリヘッダー | X-Yeap-Category |
コンソールに表示されるホストを使用してください。一部のストリームは、独自のホスト名を持つ別のサーバーグループ経由で送信します。
SMTP 送信の仕組みは次のとおりです。
- From ヘッダーには、ストリームで検証済みのドメインのアドレスを使用する必要があります。
- 各受信者(To、Cc、Bcc)には、それぞれ独自のメッセージ ID を持つ個別のコピーが送られ、1 通としてカウントされます。
- カテゴリを設定するには、
X-Yeap-Category: password-resetのようなヘッダーを追加します。このヘッダーは配信前に削除されます。使用できる文字は英字、数字、.、_、-で、最大 64 文字です。 - メッセージのサイズは最大 25 MB で、1 回の SMTP トランザクションあたりの受信者数は最大 1,000 です。
- すべてのメッセージには、
X-TM-IDヘッダー(送信ログとイベントに表示されるメッセージ ID)と、メールボックスプロバイダーのフィードバックループ用のFeedback-IDヘッダーが付与されます。 - マーケティングストリームでは、お客様が設定した
List-Unsubscribeヘッダーは、Yeap Cloud のワンクリック配信停止ヘッダーに置き換えられます。SMTP ではメッセージ本文は変更されないため、郵便住所と配信停止リンクはお客様ご自身でコンテンツに追加してください。抑制リストと配信停止をご覧ください。 - 開封とクリックのトラッキングは HTTP API でのみ利用できます。
Python 標準ライブラリを使った例:
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["From"] = "Example <noreply@example.com>"
msg["To"] = "user@example.org"
msg["Subject"] = "Reset your password"
msg["X-Yeap-Category"] = "password-reset"
msg.set_content("Click the link to reset your password: https://example.com/reset/abc")
with smtplib.SMTP("smtp.tm.yeapcloud.net", 587) as s:
s.starttls()
s.login("apikey", "ytm_your_api_key")
s.send_message(msg)SMTP 応答コード
サーバーがメッセージを拒否した場合、応答コードからその理由がわかります。4xx コードは一時的なもので、後で再試行してください。5xx コードは恒久的なもので、原因を修正してから再送信してください。
| コード | メッセージ | 原因と対処 |
|---|---|---|
535 5.7.8 | Authentication failed / API key revoked | ユーザー名またはキーが誤っているか、キーが失効しています。ユーザー名は apikey である必要があります。 |
454 4.7.0 | Temporary authentication failure / Too many authentication failures | サーバーの準備がまだできていないか、お客様の IP のログイン失敗回数が多すぎます。しばらく待ってから再試行してください。 |
451 4.7.1 | Stream is paused | ストリームが自動的に一時停止されました。ストリームに表示される理由を確認し、サポートにお問い合わせください。 |
550 5.7.1 | Stream is banned / suspended / terminated | ストリームが禁止された、サブスクリプションが停止された、またはストリームが解放されました。 |
550 5.7.1 | From domain … is not verified for this stream | ドメインを検証するか、ドメインがこのストリームと共用されているか、このストリームにバインドされているかを確認してください。 |
550 5.7.1 | Sandbox mode: recipient is not a verified address | ストリームがサンドボックスにあります。受信者を検証するか、お客様自身のドメインに送信してください。 |
550 5.7.1 | Recipient is on a suppression list / All recipients are suppressed | アドレスが抑制されています(バウンス、苦情、配信停止、または手動)。 |
452 4.7.1 | Hourly sending limit reached, try later | 1 時間あたりの上限(またはサンドボックスの 1 日あたりの上限)に達しました。次の時間帯に再試行してください。 |
550 5.7.1 | Monthly sending quota exhausted | 月間送信量を使い切り、超過も許可されていません(無料プランの場合、または超過分の支出上限に達した場合)。 |
452 4.5.3 | Too many recipients | 1 回のトランザクションの受信者が 1,000 を超えています。 |
553 5.1.3 | Invalid recipient address | 受信者アドレスの形式が正しくありません。 |
554 5.7.1 | Message rejected: virus detected | メッセージにウイルスが含まれていました。ストリームは直ちに禁止され、すべての API キーが失効します。 |
554 5.7.1 | Message rejected as spam | コンテンツがスパムと判定されました。拒否が繰り返されるとストリームが一時停止されます。 |
451 4.3.0 | Content scanner unavailable, try again later | マーケティングメールはスキャン後にのみ受け付けられます。後で再試行してください。それ以外の 451 4.3.0 応答は一時的なサーバーエラーです。再試行してください。 |
554 5.6.0 | Malformed message headers | メッセージヘッダーを修正してください。 |
HTTP API
| 項目 | 値 |
|---|---|
| ベース URL | https://api.tm.yeapcloud.net/v1(https://api.yeap.cloud/api/tm/v1 でも利用可能) |
| 認証 | Authorization: Bearer ytm_your_api_key |
| 形式 | リクエストとレスポンスの本文は JSON、Content-Type: application/json |
| レート制限 | API キーあたり毎分 600 リクエスト |
エラー時は、HTTP ステータスコードと次のような本文が返されます。
{"error": {"code": "invalid_request", "message": "subject is required (single line)"}}| HTTP ステータス | error.code | 意味 |
|---|---|---|
| 400 | invalid_json, invalid_request | 本文が JSON オブジェクトではない、またはバッチが空か大きすぎます |
| 401 | unauthorized | API キーがない、形式が不正、失効済み、または不明です |
| 403 | stream_paused, stream_banned, stream_suspended | ストリームから送信できません |
| 403 | from_domain_unverified, invalid_from | From ドメインがこのストリームで検証されていない、または From アドレスが無効です |
| 403 | postal_address_required | 郵便住所が未設定のマーケティングストリームです。マーケティング設定タブで入力してください。 |
| 403 | virus | 添付ファイルにウイルスが含まれていました。ストリームは禁止されます。 |
| 404 | not_found | このストリームにそのメッセージは存在しません |
| 422 | invalid_request | フィールドが不足しているか無効です。message にどのフィールドかが示されます。 |
| 429 | rate_limited | 1 分間のリクエストが 600 を超えました。間隔をあけて再試行してください。 |
| 503 | no_node | 現在利用できる送信サーバーがありません。後で再試行してください。 |
メッセージの送信:POST /v1/send
| フィールド | 型 | 説明 |
|---|---|---|
from | string | 必須。noreply@example.com や Example <noreply@example.com> などのアドレス 1 つ。ドメインはストリームで検証済みである必要があります。 |
to | string または array | 必須。アドレス 1 つ、カンマ区切りの文字列、または配列。配列の要素は {"email": "...", "name": "..."} 形式のオブジェクトでも構いません。 |
cc, bcc | string または array | 任意。形式は to と同じです。Bcc のアドレスはヘッダーに表示されません。 |
reply_to | string または array | 任意。Reply-To アドレス。 |
subject | string | 必須。1 行、最大 998 文字。 |
html, text | string | 少なくとも一方が必須です。最良の結果を得るには両方を送信してください。 |
headers | object | 任意の追加ヘッダー({"X-Campaign": "spring"} など)。標準ヘッダー(From、To、Subject、Reply-To、Message-ID、List-Unsubscribe など)はここでは設定できません。 |
attachments | array | 任意。要素は {"filename": "invoice.pdf", "content_base64": "...", "type": "application/pdf"}。最大 10 ファイル、合計 10 MB まで。 |
category | string | 任意。英字、数字、.、_、-、最大 64 文字。 |
tags | 文字列の array | 任意。独自の絞り込み用のタグを最大 10 個、各タグ最大 64 文字。 |
track_opens, track_clicks | boolean | 任意。このメッセージの開封トラッキング(トラッキングピクセル)とクリックトラッキング(リンクを t.tm.yeapcloud.net 経由に書き換え)のオン/オフを切り替えます。HTML のみ。省略した場合はストリームの既定値が適用されます。どちらも既定ではオフです。 |
variables | object | 任意。subject、html、text 内の {{name}} プレースホルダーを置き換えます。html では値が HTML エスケープされます。不明なプレースホルダーはそのまま残ります。 |
1 回の呼び出しで指定できる受信者は、to、cc、bcc の合計で最大 50 です。各受信者には、独自のメッセージ ID を持つ個別のコピーが送られます。多数の相手に異なる内容を送信するには、バッチエンドポイントを使用してください。
例:
curl -X POST https://api.tm.yeapcloud.net/v1/send \
-H "Authorization: Bearer ytm_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"from": "Example <noreply@example.com>",
"to": ["alice@example.org"],
"subject": "Your order {{order_id}} has shipped",
"html": "<p>Hi {{name}}, your order is on its way.</p>",
"text": "Hi {{name}}, your order is on its way.",
"category": "shipping",
"tags": ["order"],
"variables": {"name": "Alice", "order_id": "A-1024"}
}'レスポンス:
{
"message_ids": ["01JAQ3Z9V8K4M2N6P7R5S1T0XW"],
"rejected": []
}message_ids には受け付けられたコピーが一覧表示されます。rejected には送信されなかった受信者が、それぞれ rcpt と reason 付きで一覧表示されます。一部、あるいはすべての受信者が拒否されても呼び出し自体は成功する場合があるため、必ず rejected を確認してください。
reason | 意味 |
|---|---|
invalid_recipient | アドレスが無効です |
suppressed:<scope>:<reason> | アドレスが抑制リストに含まれています(例:suppressed:global:hard_bounce) |
sandbox_recipient_not_verified | ストリームがサンドボックスにあり、その受信者は許可されていません |
rate_limited_hourly, rate_limited_sandbox_or_hourly | 1 時間あたりの上限(またはサンドボックスの 1 日あたりの上限)に達しました |
monthly_quota_exceeded | 月間送信量を使い切り、超過も許可されていません |
enqueue_failed | メッセージをキューに入れられませんでした。クォータにはカウントされません。再試行してください。 |
requests を使った Python の例:
import requests
resp = requests.post(
"https://api.tm.yeapcloud.net/v1/send",
headers={"Authorization": "Bearer ytm_your_api_key"},
json={
"from": "Example <noreply@example.com>",
"to": "alice@example.org",
"subject": "Welcome",
"html": "<p>Welcome aboard!</p>",
"text": "Welcome aboard!",
"category": "welcome",
},
timeout=30,
)
resp.raise_for_status()
result = resp.json()
print(result["message_ids"], result["rejected"])一括送信:POST /v1/batch
1 回のリクエストで最大 500 件のメッセージを送信できます。各要素のフィールドは /v1/send と同じです。
{
"messages": [
{"from": "noreply@example.com", "to": "a@example.org", "subject": "Hi A", "text": "Hello A"},
{"from": "noreply@example.com", "to": "b@example.org", "subject": "Hi B", "text": "Hello B"}
]
}レスポンスには、メッセージごとの結果が同じ順序で 1 つずつ含まれます。
{
"results": [
{"index": 0, "message_ids": ["01JAQ..."], "rejected": []},
{"index": 1, "error": {"code": "invalid_request", "message": "subject is required (single line)"}, "rejected": []}
]
}メッセージの照会:GET /v1/messages
| クエリパラメーター | 説明 |
|---|---|
status | ステータスで絞り込みます:queued、delivered、deferred、bounced、complained、rejected、failed |
to | 受信者アドレスで絞り込みます |
since | この日時以降に作成されたメッセージのみ(2026-10-01T00:00:00Z など) |
limit | 1 ページあたりの件数、1–100(既定は 50) |
before | 次のページを取得するには、前のレスポンスの next_before の値を渡します |
レスポンスは {"data": [...], "next_before": "..."} です。最後のページでは next_before が null になります。メッセージは 30 日間保持されます。
GET /v1/messages/{id} は、1 件のメッセージとそのイベントを返します。
{
"id": "01JAQ3Z9V8K4M2N6P7R5S1T0XW",
"stream_id": 12,
"source": "api",
"to": "alice@example.org",
"from": "Example <noreply@example.com>",
"subject": "Welcome",
"category": "welcome",
"tags": [],
"status": "delivered",
"smtp_code": 250,
"smtp_response": "250 2.0.0 OK",
"opened_at": null,
"clicked_at": null,
"unsubscribed_at": null,
"created_at": "2026-10-20 10:15:02",
"updated_at": "2026-10-20 10:15:04",
"events": [
{"type": "delivered", "at": "2026-10-20 10:15:04", "rcpt": "alice@example.org", "smtp_code": 250, "mx": "mx.example.org"}
]
}抑制リスト:/v1/suppressions
これらのエンドポイントは、API キーが属するストリームの抑制リストを管理します。
| リクエスト | 本文またはクエリ | レスポンス |
|---|---|---|
GET /v1/suppressions | クエリ email(任意)、limit(1–500、既定は 100)、offset | {"data": [{"id", "scope", "email", "reason", "category", "note", "created_at"}]} |
POST /v1/suppressions | {"email": "..."} または {"emails": [...]}(最大 1,000)、任意で category | {"added": 2, "invalid": []} |
DELETE /v1/suppressions | {"email": "..."}、任意で category(本文またはクエリ) | {"removed": 1} |
API で追加したアドレスの理由は manual になります。アカウント全体の抑制とグローバル抑制は API では変更できません。抑制リストと配信停止をご覧ください。