邮件
事务性邮件,支持模板、域名验证与投递追踪。
1. 概览
https://api.infrai.cc/v1/emailAuthorization: Bearer $INFRAI_API_KEY# Call any /v1/email capability over raw HTTP — no SDK to install.
# curl:
curl https://api.infrai.cc/v1/email/... \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json"2. 方法 (17)
2.1email.send
发送事务性邮件;支持模板与附件。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
to | string | string[] | 必填 | 收件地址或地址列表。 |
subject | string | 必填 | 邮件主题。 |
text | string | 可选 | 纯文本正文。 |
html | string | 可选 | HTML 正文。 |
from | string | 可选 | 发件地址(需已验证域名)。 |
cc | string[] | 可选 | 抄送地址。 |
bcc | string[] | 可选 | 密送地址。 |
template_id | string | 可选 | 用于渲染的模板 id(替代正文)。 |
template_vars | Record<string, unknown> | 可选 | 传入模板的变量。 |
attachments | Array<{ filename, content, mime? }> | 可选 | 要附加的文件。 |
vendor | string | 可选 | 固定使用某个供应商,而非自动路由。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
EmailRecord { email_id, state, to, subject, vendor, created_at }| 名称 | 类型 | 说明 |
|---|---|---|
message_id | string | message的唯一标识符pattern: ^msg_[A-Za-z0-9]{20,}$ |
vendor_message_id | string | null | 上游供应商分配的消息标识符 |
from_used | string | 实际用于投递的发件邮箱地址 |
mode | "default_vendor" | "verified_domain" | 投递模式或操作模式 |
scheduled_at | string | null | ISO 8601 时间戳:the resource is scheduled to activate(ISO 8601)format: date-time |
accepted_recipients | string[] | recipient email addresses that were accepted列表 |
suppressed_recipients | string[] | recipient email addresses that were suppressed列表 |
metadata | object | null | 本次发送的成本/供应商披露(成本透明契约面)。为内核 ResultMetadata 的超集,另带邮件专属 `mode` 字段;供应商路由解析后存在(仅当所有收件人在尝试投递前已被抑制时缺失……即便如此通常仍以 cost_usd=0 存在)。 |
metadata.request_id | string | UUID v7。 |
metadata.trace_id | string | 分布式追踪标识符 |
metadata.timestamp | string | 数据点的 Unix 时间戳format: date-time |
metadata.latency_ms | integer | 操作延迟(毫秒)≥ 0 |
metadata.entry_form | any | 入口格式(rest、mcp、sdk) |
metadata.cost_usd | number | 此操作成本(美元)≥ 0 |
metadata.cost_cny | number | 此请求成本(人民币)≥ 0 |
metadata.vendor | string | 适配器名称;引用 VendorRegistry。 |
metadata.vendor_region | "china" | "western" | 处理此请求的供应商区域 |
metadata.markup_pct | number | 供应商成本之上的加价百分比 |
metadata.mode | "default_vendor" | "verified_domain" | 本次发送解析出的邮件投递模式(邮件专属字段,不存在于通用 kernel ResultMetadata)。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/send \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/send",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'to': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"to": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"to": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"to": "sample"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/send", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/send"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"to\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/send");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"to\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/send");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"to\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/send")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"to": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/send")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"to": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.2email.get
按 id 获取单条邮件记录。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | 邮件记录 id。 |
返回
EmailRecord| 名称 | 类型 | 说明 |
|---|---|---|
message_id | string | 消息存档 ID(msg_ + 十六进制)。pattern: ^msg_[A-Za-z0-9]{12,}$ |
state | string | 聚合状态——参见 enums/email_state.yaml。 |
channel | "email" | 存档记录的投递渠道。 |
to | any | 消息发送的收件人(字符串或数组,按提交时的格式)。 |
vendor | string | 实际派发消息的供应商。 |
created_at | number | string | 消息存档时的 Unix 秒数(或 ISO-8601)。 |
per_recipient_state | object | 可选——收件人邮箱到逐收件人状态的映射(仅在配置了投递事件 Webhook 管道时填充)。 |
first_event_at | string | 可选——首次投递事件时间戳(从 Webhook 派生)。format: date-time |
last_event_at | string | 可选——最近投递事件时间戳(从 Webhook 派生)。format: date-time |
counts | object | 可选——按事件类型的统计(delivered/bounced/opened/clicked/...),从 Webhook 派生。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/email/get/ID \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/get/ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/get/ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/get/ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/email/get/ID", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/get/ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/email/get/ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/get/ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/get/ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/email/get/ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.3email.suppression.add
将某地址加入抑制名单。
返回
SuppressionRecord| 名称 | 类型 | 说明 |
|---|---|---|
email | string | 邮箱地址format: email |
reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | 当前状态或操作原因 |
added_at | string | 资源添加时间(ISO 8601)format: date-time |
last_attempt_at | string | null | 此条目上次阻止发送的时间。format: date-time |
attempt_count_blocked | integer | null | delivery attempts blocked by this suppression数量≥ 0 |
notes | string | null | 关于此抑制的自由文本备注 |
scope | "account" | "domain" | 此资源的适用范围 |
domain_scope | string | null | 当 scope=domain 时,具体的已验证域名。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/suppression/add \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/suppression/add",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'email': 'user@example.com'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/add",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"email": "user@example.com"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/add",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"email": "user@example.com"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"email": "user@example.com"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/suppression/add", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/suppression/add"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"email\": \"user@example.com\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/suppression/add");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"email\": \"user@example.com\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/suppression/add");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"email\": \"user@example.com\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/suppression/add")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"email": "user@example.com"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/suppression/add")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"email": "user@example.com"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.4email.domain.verify
验证发件域名并返回所需 DNS 记录。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | 要验证的域名。 |
返回
{ verified, records: Array<{ type, name, value }> }| 名称 | 类型 | 说明 |
|---|---|---|
domain | string | 顶级域名,如 "yourdomain.com"。 |
domain_id | string | domain的唯一标识符pattern: ^dom_[A-Za-z0-9]{20,}$ |
status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | 当前资源状态 |
dns_records | object[] | 域名验证所需的 DNS 记录 |
dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | 资源类型标识 |
dns_records[].name | string | 完整限定 DNS 名称。 |
dns_records[].value | string | DNS 记录或配置的值 |
dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | DNS 记录用途 |
dns_records[].ttl_recommended | integer | 建议 TTL(秒)≥ 60default: 3600 |
checks | object | null | 逐条记录检查状态("ok"/"pending"/"mismatch"/...)。 |
warm_up_state | "not_started" | "in_progress" | "complete" | null | 域名当前预热状态 |
daily_limit_current | integer | null | 当前每日发送限额≥ 0 |
daily_limit_target | integer | null | 预热后目标每日发送限额≥ 0 |
created_at | string | 资源创建时间(ISO 8601)format: date-time |
verified_at | string | null | ISO 8601 时间戳:verification was completed(ISO 8601)format: date-time |
expires_at | string | null | DKIM 轮换到期时间(建议 1 年)。format: date-time |
rotated | boolean | 仅在 email.domain.rotate_dkim 响应中存在:DKIM 密钥轮换发起后为 true(在 DNS 中观测到新记录前状态回落为 pending_dns)。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/domain/verify \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"domain": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/domain/verify",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'domain': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/verify",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"domain": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/verify",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"domain": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"domain": "sample"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/domain/verify", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/domain/verify"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"domain\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/domain/verify");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"domain\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/domain/verify");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"domain\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/domain/verify")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"domain": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/domain/verify")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"domain": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.5email.batch.send
批量个性化发送,最多 100 条不同邮件共用一个 idempotency_key(批量直通,单条不重复计费)。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
messages | EmailSendOptions[] | 必填 | 邮件数组,每项是一个完整的 EmailSendRequest,各自带收件人与模板变量,1 到 100 条。1–100 items |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
BatchSendResult { batch_id, results }| 名称 | 类型 | 说明 |
|---|---|---|
batch_id | string | batch job的唯一标识符pattern: ^batch_[A-Za-z0-9]{20,}$ |
results | object[] | individual results from a batch operation列表 |
results[].index | integer | 此消息在请求 messages[] 数组中的位置。≥ 0 |
results[].message_id | string | null | 此消息入队失败时为 null。pattern: ^msg_[A-Za-z0-9]{20,}$ |
results[].to | string | string[] | - |
results[].status | "accepted" | "suppressed" | "failed" | - |
results[].error | string | null | status=failed 时的错误码(如 SUPPRESSED_RECIPIENT)。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/batch/send \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messages": [{"to": "sample"}]}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/batch/send",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'messages': [{'to': 'sample'}]},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/batch/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"messages": [{"to": "sample"}]}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/batch/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"messages": [{"to": "sample"}]}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"messages": [{"to": "sample"}]}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/batch/send", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/batch/send"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"messages\": [{\"to\": \"sample\"}]}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/batch/send");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"messages\": [{\"to\": \"sample\"}]}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/batch/send");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"messages\": [{\"to\": \"sample\"}]}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/batch/send")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"messages": [{"to": "sample"}]}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/batch/send")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"messages": [{"to": "sample"}]}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.6email.event.list
查询指定邮件的投递事件时间线。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
message_id | string | 必填 | 必填。要查询事件时间线的邮件 message_id。 |
type | string | 可选 | 按事件类型过滤(如 delivered、bounced、opened)。 |
limit | number | 可选 | 返回的最大条数。 |
cursor | string | 可选 | 分页游标。 |
返回
{ items: EmailEvent[], next_cursor? }| 名称 | 类型 | 说明 |
|---|---|---|
items | object[] | resource records列表 |
items[].type | "queued" | "sent" | "delivered" | "opened" | "clicked" | "bounced" | "complained" | "deferred" | "expired" | "cancelled" | "unsubscribed" | "auto_suppressed" | 资源类型标识 |
items[].at | string | 事件的 ISO 8601 时间戳format: date-time |
items[].recipient | string | 收件人邮箱地址format: email |
items[].message_id | string | null | message的唯一标识符pattern: ^msg_[A-Za-z0-9]{20,}$ |
items[].meta | object | null | 事件专属元数据(ip / user_agent / url / bounce_type / reason)。 |
count | integer | items in this page数量≥ 0 |
next_cursor | string | null | 传入 event.list() 以获取下一页。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/email/event/list \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/event/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/event/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/event/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/email/event/list", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/event/list"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/email/event/list");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/event/list");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/event/list")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/email/event/list")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.7email.suppression.check
查询某个收件地址是否在抑制名单中。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
email | string | 必填 | 收件邮箱地址。 |
返回
SuppressionCheckResult { is_suppressed, record? }| 名称 | 类型 | 说明 |
|---|---|---|
email | string | 被检查的邮箱地址。 |
suppressed | boolean | 该地址是否当前被抑制 |
reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | 当前抑制的原因。仅在 suppressed=true 时存在。 |
added_at | string | 此抑制被添加的 ISO 8601 时间戳。仅在 suppressed=true 时存在。format: date-time |
last_attempt_at | string | null | 此条目上次阻止发送的时间。仅在 suppressed=true 时存在。format: date-time |
attempt_count_blocked | integer | null | delivery attempts blocked by this suppression. Present only when suppressed=true.数量≥ 0 |
notes | string | null | 关于此抑制的自由文本备注。仅在 suppressed=true 时存在。 |
scope | "account" | "domain" | 此抑制条目的适用范围。仅在 suppressed=true 时存在。 |
domain_scope | string | null | 当 scope=domain 时,具体的已验证域名。仅在 suppressed=true 时存在。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/email/suppression/check/EMAIL \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/suppression/check/EMAIL",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/check/EMAIL",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/check/EMAIL",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/email/suppression/check/EMAIL", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/suppression/check/EMAIL"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/email/suppression/check/EMAIL");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/suppression/check/EMAIL");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/suppression/check/EMAIL")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/email/suppression/check/EMAIL")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.8email.suppression.list
列出抑制名单中的收件地址。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
reason | string | 可选 | 按抑制原因过滤(如 bounce、complaint、manual)。 |
limit | number | 可选 | 返回的最大条数。 |
cursor | string | 可选 | 分页游标。 |
返回
{ items: SuppressionRecord[], next_cursor? }| 名称 | 类型 | 说明 |
|---|---|---|
items | object[] | resource records列表 |
items[].email | string | 邮箱地址format: email |
items[].reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | 当前状态或动作的原因 |
items[].added_at | string | 此资源添加的 ISO 8601 时间戳format: date-time |
items[].last_attempt_at | string | null | 此条目上次阻止发送的时间。format: date-time |
items[].attempt_count_blocked | integer | null | delivery attempts blocked by this suppression数量≥ 0 |
items[].notes | string | null | 关于此抑制的自由文本备注 |
items[].scope | "account" | "domain" | 此资源的适用范围 |
items[].domain_scope | string | null | 当 scope=domain 时,具体的已验证域名。 |
count | integer | items in this page数量≥ 0 |
next_cursor | string | null | 获取下一页的不透明游标;null 或不存在表示最后一页 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/email/suppression/list \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/suppression/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/email/suppression/list", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/suppression/list"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/email/suppression/list");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/suppression/list");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/suppression/list")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/email/suppression/list")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.9email.suppression.delete
将某地址移出抑制名单,恢复对其投递。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
email | string | 必填 | 收件邮箱地址。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
{ deleted: boolean }| 名称 | 类型 | 说明 |
|---|---|---|
email | string | null | 已从抑制列表中移除的邮箱地址 |
deleted | boolean | 抑制条目是否已移除(与 `found` 同值:条目存在且已从抑制存储中移除)。 |
found | boolean | 删除调用前该邮箱是否存在抑制条目。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X DELETE https://api.infrai.cc/v1/email/suppression/delete/EMAIL \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/email/suppression/delete/EMAIL",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/delete/EMAIL",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/delete/EMAIL",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.infrai.cc/v1/email/suppression/delete/EMAIL", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/suppression/delete/EMAIL"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("DELETE", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.infrai.cc/v1/email/suppression/delete/EMAIL");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/suppression/delete/EMAIL");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/suppression/delete/EMAIL")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.delete("https://api.infrai.cc/v1/email/suppression/delete/EMAIL")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.10email.domain.list
列出账户下已添加的发信域名。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
limit | number | 可选 | 返回的最大条数。 |
cursor | string | 可选 | 分页游标。 |
返回
{ items: DomainVerification[], next_cursor? }| 名称 | 类型 | 说明 |
|---|---|---|
records | object[] | resource records列表 |
records[].domain | string | 顶级域名,如 "yourdomain.com"。 |
records[].domain_id | string | domain的唯一标识符pattern: ^dom_[A-Za-z0-9]{20,}$ |
records[].status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | 此资源当前状态 |
records[].dns_records | object[] | 域名验证所需的 DNS 记录 |
records[].dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | 资源类型标识 |
records[].dns_records[].name | string | 完整限定 DNS 名称。 |
records[].dns_records[].value | string | DNS 记录或配置的值 |
records[].dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | DNS 记录用途 |
records[].dns_records[].ttl_recommended | integer | 建议 TTL(秒)≥ 60default: 3600 |
records[].checks | object | null | 逐条记录检查状态("ok"/"pending"/"mismatch"/...)。 |
records[].warm_up_state | "not_started" | "in_progress" | "complete" | null | 域名当前预热状态 |
records[].daily_limit_current | integer | null | 当前每日发送限额≥ 0 |
records[].daily_limit_target | integer | null | 预热后目标每日发送限额≥ 0 |
records[].created_at | string | 此资源创建的 ISO 8601 时间戳format: date-time |
records[].verified_at | string | null | 验证完成的 ISO 8601 时间戳format: date-time |
records[].expires_at | string | null | DKIM 轮换到期时间(建议 1 年)。format: date-time |
records[].rotated | boolean | 仅在 email.domain.rotate_dkim 响应中存在:DKIM 密钥轮换发起后为 true(在 DNS 中观测到新记录前状态回落为 pending_dns)。 |
total_count | integer | 跨所有页的总条目数≥ 0 |
next_cursor | string | null | 传入 domain.list() 以获取下一页。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/email/domain/list \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/domain/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/email/domain/list", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/domain/list"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/email/domain/list");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/domain/list");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/domain/list")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/email/domain/list")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.11email.domain.get
获取某个发信域名的验证状态与信誉信息。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | 要验证的域名。 |
返回
DomainGetResult { verification, reputation }| 名称 | 类型 | 说明 |
|---|---|---|
verification | object | 域名验证状态和 DNS 记录 |
verification.domain | string | 顶级域名,如 "yourdomain.com"。 |
verification.domain_id | string | domain的唯一标识符pattern: ^dom_[A-Za-z0-9]{20,}$ |
verification.status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | 此资源当前状态 |
verification.dns_records | object[] | 域名验证所需的 DNS 记录 |
verification.dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | 资源类型标识 |
verification.dns_records[].name | string | 完整限定 DNS 名称。 |
verification.dns_records[].value | string | DNS 记录或配置的值 |
verification.dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | DNS 记录用途 |
verification.dns_records[].ttl_recommended | integer | 建议 TTL(秒)≥ 60default: 3600 |
verification.checks | object | null | 逐条记录检查状态("ok"/"pending"/"mismatch"/...)。 |
verification.warm_up_state | "not_started" | "in_progress" | "complete" | null | 域名当前预热状态 |
verification.daily_limit_current | integer | null | 当前每日发送限额≥ 0 |
verification.daily_limit_target | integer | null | 预热后目标每日发送限额≥ 0 |
verification.created_at | string | 此资源创建的 ISO 8601 时间戳format: date-time |
verification.verified_at | string | null | 验证完成的 ISO 8601 时间戳format: date-time |
verification.expires_at | string | null | DKIM 轮换到期时间(建议 1 年)。format: date-time |
verification.rotated | boolean | 仅在 email.domain.rotate_dkim 响应中存在:DKIM 密钥轮换发起后为 true(在 DNS 中观测到新记录前状态回落为 pending_dns)。 |
reputation | object | null | 域名验证并开始预热前为 null。 |
reputation.domain | string | 域名 |
reputation.tier | "warming_up" | "established" | "trusted" | "throttled" | "suspended" | 当前订阅档位(standard / pro / enterprise) |
reputation.current_daily_cap | integer | 当前每日发送上限≥ 0 |
reputation.used_today | integer | emails sent today数量≥ 0 |
reputation.bounce_rate_30d | number | 最近 30 天退信率0–1 |
reputation.complaint_rate_30d | number | 最近 30 天投诉率0–1 |
reputation.days_in_current_tier | integer | 当前预热档位已持续天数≥ 0 |
reputation.next_tier | "warming_up" | "established" | "trusted" | "throttled" | "suspended" | null | 下一个预热档位 |
reputation.next_tier_requirements | object | null | 升级所需的具体阈值和剩余时长。 |
reputation.throttle_risk | "low" | "medium" | "high" | 基于近期域名信誉指标的当前限流风险。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/email/domain/get/DOMAIN \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/domain/get/DOMAIN",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/get/DOMAIN",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/get/DOMAIN",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/email/domain/get/DOMAIN", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/domain/get/DOMAIN"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/email/domain/get/DOMAIN");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/domain/get/DOMAIN");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/domain/get/DOMAIN")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/email/domain/get/DOMAIN")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.12email.domain.delete
删除一个已添加的发信域名。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | 要验证的域名。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
{ deleted: boolean }| 名称 | 类型 | 说明 |
|---|---|---|
domain | string | null | 已删除的域名 |
deleted | boolean | 域名是否已删除(与 `found` 同值:域名存在且已从自管发信域存储中移除)。 |
found | boolean | 删除调用前该域名是否存在域名验证记录。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X DELETE https://api.infrai.cc/v1/email/domain/delete/DOMAIN \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/email/domain/delete/DOMAIN",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/delete/DOMAIN",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/delete/DOMAIN",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.infrai.cc/v1/email/domain/delete/DOMAIN", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/domain/delete/DOMAIN"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("DELETE", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.infrai.cc/v1/email/domain/delete/DOMAIN");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/domain/delete/DOMAIN");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/domain/delete/DOMAIN")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.delete("https://api.infrai.cc/v1/email/domain/delete/DOMAIN")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.13email.domain.rotate_dkim
为发信域名轮换 DKIM 密钥,返回需配置的新 DNS 记录。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | 要验证的域名。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
DomainVerification { domain, status, dns_records, ... }| 名称 | 类型 | 说明 |
|---|---|---|
domain | string | 顶级域名,如 "yourdomain.com"。 |
domain_id | string | domain的唯一标识符pattern: ^dom_[A-Za-z0-9]{20,}$ |
status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | 当前资源状态 |
dns_records | object[] | 域名验证所需的 DNS 记录 |
dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | 资源类型标识 |
dns_records[].name | string | 完整限定 DNS 名称。 |
dns_records[].value | string | DNS 记录或配置的值 |
dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | DNS 记录用途 |
dns_records[].ttl_recommended | integer | 建议 TTL(秒)≥ 60default: 3600 |
checks | object | null | 逐条记录检查状态("ok"/"pending"/"mismatch"/...)。 |
warm_up_state | "not_started" | "in_progress" | "complete" | null | 域名当前预热状态 |
daily_limit_current | integer | null | 当前每日发送限额≥ 0 |
daily_limit_target | integer | null | 预热后目标每日发送限额≥ 0 |
created_at | string | 资源创建时间(ISO 8601)format: date-time |
verified_at | string | null | ISO 8601 时间戳:verification was completed(ISO 8601)format: date-time |
expires_at | string | null | DKIM 轮换到期时间(建议 1 年)。format: date-time |
rotated | boolean | 仅在 email.domain.rotate_dkim 响应中存在:DKIM 密钥轮换发起后为 true(在 DNS 中观测到新记录前状态回落为 pending_dns)。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/domain/rotate_dkim/DOMAIN")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.14email.template.create
创建一个邮件模板。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 必填 | 模板名称,账户内唯一。1–128 chars |
subject | string | 必填 | 主题模板,可包含 {{var}} 占位符。 |
html | string | 必填 | HTML 正文模板,可包含 {{var}}、{{#section}}、{{^inverted}}。 |
body_text | string | 可选 | 纯文本备用正文。 |
variables | Record<string, string> | 可选 | 声明的变量及类型,如 { name: 'string' }。 |
default_vars | Record<string, unknown> | 可选 | 发送时变量缺失所用的默认值。 |
tags | string[] | 可选 | 模板标签列表。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
Template { template_id, name, subject, html, ... }| 名称 | 类型 | 说明 |
|---|---|---|
template_id | string | 用于渲染的模板标识符pattern: ^tmpl_[A-Za-z0-9]{20,}$ |
name | string | 账户内唯一。1–128 chars |
subject | string | 可包含双花括号占位符(如 var)。 |
html | string | HTML 正文;可包含双花括号占位符(var、#section、^inverted)。 |
body_text | string | null | 纯文本备选。 |
variables | object | null | 声明的变量:name,类型为 'string'、'int'、'bool'、'array' 或 'object'。 |
default_vars | object | null | 发送时变量缺失所用的默认值。 |
tags | string[] | null | 分类与筛选标签 |
created_at | string | 资源创建时间(ISO 8601)format: date-time |
updated_at | string | 资源最后更新时间(ISO 8601)format: date-time |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/template/create \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "example", "subject": "sample", "html": "<h1>Hello from infrai</h1>"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/template/create",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'name': 'example', 'subject': 'sample', 'html': '<h1>Hello from infrai</h1>'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/create",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "example", "subject": "sample", "html": "<h1>Hello from infrai</h1>"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/create",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "example", "subject": "sample", "html": "<h1>Hello from infrai</h1>"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"name": "example", "subject": "sample", "html": "<h1>Hello from infrai</h1>"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/template/create", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/template/create"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"name\": \"example\", \"subject\": \"sample\", \"html\": \"<h1>Hello from infrai</h1>\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/template/create");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"name\": \"example\", \"subject\": \"sample\", \"html\": \"<h1>Hello from infrai</h1>\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/template/create");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"name\": \"example\", \"subject\": \"sample\", \"html\": \"<h1>Hello from infrai</h1>\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/template/create")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"name": "example", "subject": "sample", "html": "<h1>Hello from infrai</h1>"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/template/create")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"name": "example", "subject": "sample", "html": "<h1>Hello from infrai</h1>"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.15email.template.update
更新一个已有的邮件模板。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | 用于渲染的模板 id(替代正文)。 |
subject | string | 可选 | 主题模板,可包含 {{var}} 占位符。 |
html | string | 可选 | HTML 正文模板,可包含 {{var}}、{{#section}}、{{^inverted}}。 |
body_text | string | 可选 | 纯文本备用正文。 |
variables | Record<string, string> | 可选 | 声明的变量及类型,如 { name: 'string' }。 |
default_vars | Record<string, unknown> | 可选 | 发送时变量缺失所用的默认值。 |
tags | string[] | 可选 | 模板标签列表。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
Template { template_id, name, subject, html, ... }| 名称 | 类型 | 说明 |
|---|---|---|
template_id | string | 用于渲染的模板标识符pattern: ^tmpl_[A-Za-z0-9]{20,}$ |
name | string | 账户内唯一。1–128 chars |
subject | string | 可包含双花括号占位符(如 var)。 |
html | string | HTML 正文;可包含双花括号占位符(var、#section、^inverted)。 |
body_text | string | null | 纯文本备选。 |
variables | object | null | 声明的变量:name,类型为 'string'、'int'、'bool'、'array' 或 'object'。 |
default_vars | object | null | 发送时变量缺失所用的默认值。 |
tags | string[] | null | 分类与筛选标签 |
created_at | string | 资源创建时间(ISO 8601)format: date-time |
updated_at | string | 资源最后更新时间(ISO 8601)format: date-time |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X PATCH https://api.infrai.cc/v1/email/template/update/ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.patch(
"https://api.infrai.cc/v1/email/template/update/ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/update/ID",
{
method: "PATCH",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/update/ID",
{
method: "PATCH",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{}`)
req, _ := http.NewRequest("PATCH", "https://api.infrai.cc/v1/email/template/update/ID", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/template/update/ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("PATCH", HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("PATCH"), "https://api.infrai.cc/v1/email/template/update/ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/template/update/ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/template/update/ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.patch("https://api.infrai.cc/v1/email/template/update/ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.16email.template.delete
删除一个邮件模板。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | 用于渲染的模板 id(替代正文)。 |
idempotency_key | string | 可选 | 可选去重 key;相同重试将返回同一结果。 |
返回
{ deleted: boolean }| 名称 | 类型 | 说明 |
|---|---|---|
template_id | string | null | 已删除的模板标识符 |
deleted | boolean | 模板是否已删除(与 `found` 同值:模板存在且已从模板存储中移除)。 |
found | boolean | 删除调用前是否存在此 ID 的模板。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X DELETE https://api.infrai.cc/v1/email/template/delete/ID \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/email/template/delete/ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/delete/ID",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/delete/ID",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.infrai.cc/v1/email/template/delete/ID", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/template/delete/ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("DELETE", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.infrai.cc/v1/email/template/delete/ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/template/delete/ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/template/delete/ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.delete("https://api.infrai.cc/v1/email/template/delete/ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.17email.template.preview
用给定变量渲染模板,预览主题、HTML、文本及缺失变量。
参数
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | 用于渲染的模板 id(替代正文)。 |
vars | Record<string, unknown> | 必填 | 用于渲染的变量值,会与模板的 default_vars 合并。 |
返回
TemplatePreview { rendered_subject, rendered_html, rendered_text, missing_vars }| 名称 | 类型 | 说明 |
|---|---|---|
rendered_subject | string | 变量替换后的渲染主题行 |
rendered_html | string | 变量替换后的渲染 HTML 正文 |
rendered_text | string | null | 变量替换后的渲染纯文本正文 |
missing_vars | string[] | 模板引用但在输入和 default_vars 中均缺失的变量。 |
示例
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/email/template/preview/ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"vars": {}}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/template/preview/ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'vars': {}},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/preview/ID",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"vars": {}}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/template/preview/ID",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"vars": {}}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"vars": {}}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/email/template/preview/ID", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/email/template/preview/ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"vars\": {}}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/email/template/preview/ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"vars\": {}}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/email/template/preview/ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"vars\": {}}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/email/template/preview/ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"vars": {}}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/email/template/preview/ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"vars": {}}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}高级:指定 vendor
默认情况下 infrai 会把每次调用智能路由到最佳可用供应商——无需自己挑选 vendor。作为高级逃生口,本能力支持可选的 vendor 入参以锁定某个供应商。本能力当前所有可用 vendor 可通过该能力 id 对应的 discovery 端点实时获取——参见 discovery API。
GET /v1/discovery/{capability}email.send
3. 全部能力
本模块全部已路由能力——完整的对外 REST 契约。上方方法是带讲解的入门示例,此表是完整参考。
email.batch.sendPOST /v1/email/batch/sendSend up to 100 personalized emails under one idempotency_key (batch passthrough, not billed per message).
参数 (2)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
messages | object[] | 必填 | Each entry is a full EmailSendRequest with its own recipients / template_vars.1–100 items |
idempotency_key | string | null | 可选 | One key for the whole batch; per-message sends are not re-charged. |
email.domain.deleteDELETE /v1/email/domain/delete/{domain}Delete a previously added sender domain.
参数 (1)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | Path parameter. |
email.domain.getGET /v1/email/domain/get/{domain}Get the verification status and reputation of a sender domain.
参数 (1)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | Path parameter. |
email.domain.listGET /v1/email/domain/listList the sender domains added to the account.
无请求参数。
email.domain.rotate_dkimPOST /v1/email/domain/rotate_dkim/{domain}Rotate DKIM for a sender domain and return the new DNS records.
参数 (2)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | Path parameter. |
idempotency_key | string | null | 可选 | Client-provided idempotency key; prevents duplicate execution on retry |
email.domain.verifyPOST /v1/email/domain/verifyVerify a sender domain's DNS records to complete verification.
参数 (2)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain | string | 必填 | Sending domain to verify (e.g. mail.example.com). |
idempotency_key | string | null | 可选 | Client-provided idempotency key; prevents duplicate execution on retry |
email.event.listGET /v1/email/event/listList email delivery events (delivered, bounced, opened, clicked, complained).
无请求参数。
email.getGET /v1/email/get/{id}Get the delivery details of one email by message_id.
参数 (1)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | Path parameter. |
email.sendPOST /v1/email/sendSend a transactional email (inline body/HTML or a template) with tracking; idempotent.
参数 (21)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
to | string | string[] | 必填 | Recipient address, or an array of addresses for multiple recipients. |
cc | string[] | 可选 | Carbon copy recipients |
bcc | string[] | 可选 | Blind carbon copy recipients |
from | string | null | 可选 | Optional. Omit to use Infrai's default sender on send.infrai.cc. If you provide a custom-domain sender, that domain must be verified first. |
from_display_name | string | null | 可选 | Display name for the sender |
reply_to | string | null | 可选 | Reply-to email address |
subject | string | null | 可选 | Email subject line |
body | string | null | 可选 | Plain text body. |
html | string | null | 可选 | HTML body of the email |
template_id | string | null | 可选 | Identifier of the template used for rendering |
template_vars | object | null | 可选 | Variables to substitute in the template |
attachments | object[] | 可选 | List of email attachments |
headers | object | null | 可选 | Custom HTTP headers to include in requests or responses |
tags | string[] | 可选 | Tags for categorization and filtering |
track_opens | boolean | 可选 | Whether to track email opensdefault: false |
track_clicks | boolean | 可选 | Whether to track link clicks in the emaildefault: false |
scheduled_at | string | null | 可选 | ISO 8601 timestamp when the resource is scheduled to activateformat: date-time |
idempotency_key | string | null | 可选 | Client-provided idempotency key; prevents duplicate execution on retry |
vendor | string | null | 可选 | Pin to a specific vendor. |
message_class | "transactional" | "marketing" | 可选 | Semantic class of the message. Only transactional is currently live; marketing is reserved and fails closed.default: "transactional" |
auto_unsubscribe_link | boolean | null | 可选 | Whether to append a signed unsubscribe link. Transactional messages omit it by default; marketing-like content may still be forced to include it. |
email.suppression.addPOST /v1/email/suppression/addAdd a recipient address to the suppression list to stop future delivery; idempotent.
参数 (6)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
email | string | 必填 | Email addressformat: email |
reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | 可选 | Reason for the current state or actiondefault: "manual" |
scope | "account" | "domain" | 可选 | Scope of applicability for this resourcedefault: "account" |
domain_scope | string | null | 可选 | When scope=domain, the specific verified domain. |
notes | string | null | 可选 | Free-text notes about this suppression |
idempotency_key | string | null | 可选 | Client-provided idempotency key; prevents duplicate execution on retry |
email.suppression.checkGET /v1/email/suppression/check/{email}Check whether an address is on the suppression list.
参数 (1)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
email | string | 必填 | Path parameter. |
email.suppression.deleteDELETE /v1/email/suppression/delete/{email}Remove an address from the suppression list to resume delivery.
参数 (1)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
email | string | 必填 | Path parameter. |
email.suppression.listGET /v1/email/suppression/listList recipient addresses on the suppression list.
无请求参数。
email.template.createPOST /v1/email/template/createCreate an email template.
参数 (8)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 必填 | Unique within account.1–128 chars |
subject | string | 必填 | May contain double-brace var placeholders. |
html | string | 必填 | HTML body; may contain double-brace var, double-brace #section, double-brace ^inverted. |
body_text | string | null | 可选 | Plain-text alternative. |
variables | object | null | 可选 | Declared variables: { name: 'string' | 'int' | 'bool' | 'array' | 'object' }. |
default_vars | object | null | 可选 | Defaults used when var missing in send(). |
tags | string[] | null | 可选 | Tags for categorization and filtering |
idempotency_key | string | null | 可选 | Client-provided idempotency key; prevents duplicate execution on retry |
email.template.deleteDELETE /v1/email/template/delete/{id}Delete an email template.
参数 (1)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | Path parameter. |
email.template.previewPOST /v1/email/template/preview/{id}Render and preview a template with the given variables.
参数 (2)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | Path parameter. |
vars | object | 必填 | Variable values merged with the template's default_vars before rendering. |
email.template.updatePATCH /v1/email/template/update/{id}Update an existing email template.
参数 (8)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | Path parameter. |
subject | string | null | 可选 | May contain double-brace var placeholders. |
html | string | null | 可选 | HTML body; may contain double-brace var, double-brace #section, double-brace ^inverted. |
body_text | string | null | 可选 | Plain-text alternative. |
variables | object | null | 可选 | Template variable definitions |
default_vars | object | null | 可选 | Default variable values for the template |
tags | string[] | null | 可选 | Tags for categorization and filtering |
idempotency_key | string | null | 可选 | Client-provided idempotency key; prevents duplicate execution on retry |
4. 完整示例
本模块的生产级端到端范例:先一次性配置,再运行业务流程,尽量覆盖本模块的多数 API。
单文件可运行 Python 程序(仅标准库、无 SDK):拷贝后填入 INFRAI_API_KEY 运行,即可按真实业务流逐步体验本模块核心 API——每一步都真实调用并计费,后续步骤复用前一步返回的真实字段。12 行 helper 就是全部集成代码。
#!/usr/bin/env python3
"""Infrai · comm-email — runnable real-app example (single file, zero deps).
Copy this file, set your key, run it: every step is a REAL call to
api.infrai.cc, billed at the real (tiny) per-call price, printing the
live JSON response. Get a key at https://infrai.cc/login (Google/
GitHub sign-in grants $2 free credit); add funds at
https://infrai.cc/billing. No SDK — the 12-line helper below is the
entire integration."""
import json
import os
from urllib import error, request
KEY = os.environ.get("INFRAI_API_KEY") or "ifr_..." # <- your key
BASE = "https://api.infrai.cc"
# Same raw HTTPS POST/GET as every per-method example on this page —
# wrapped once for reuse. There is nothing else to it: no SDK.
def infrai(method, path, body=None):
req = request.Request(
BASE + path, method=method,
data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json"})
try:
with request.urlopen(req, timeout=60) as r:
return json.loads(r.read())
except error.HTTPError as e:
return json.loads(e.read())
def show(label, resp):
print(f"\n== {label} ==")
print(json.dumps(resp, indent=2, ensure_ascii=False))
return resp
# 1) email.send — POST /v1/email/send · Send a transactional email (inline body/HTML or a template) with tracking; idempotent.
ask1 = input("Your email address (sends a real email): ").strip()
r1 = show("email.send", infrai("POST", "/v1/email/send", {"to":ask1,"subject":"Welcome","html":"<p>Hi!</p>"}))
# 2) email.get — GET /v1/email/get/{id} · Get the delivery details of one email by message_id.
id_2 = (r1.get("data") or {}).get("message_id") or ""
r2 = show("email.get", infrai("GET", f"/v1/email/get/{id_2}"))
# 3) email.event.list — GET /v1/email/event/list · List the delivery event timeline for one email; message_id is required.
r3 = show("email.event.list", infrai("GET", "/v1/email/event/list"))
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."# 1) Auth: every call is a raw HTTPS request to the Infrai gateway carrying
# only your project key. No SDK, no install.
# Get your key: sign in with Google/GitHub at https://infrai.cc/login for a
# project key + $2 free credit (email sign-in starts at $0). On 402
# INSUFFICIENT_CREDIT, add funds at https://infrai.cc/billing (or POST
# /v1/account/topup and open the returned checkout_url).
export INFRAI_API_KEY="ifr_..." # from https://infrai.cc/login
# 2) email.send
curl -X POST https://api.infrai.cc/v1/email/send \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "alice@example.com", "subject": "Welcome", "html": "<p>Hi!</p>"}'
# 3) email.get
curl -X GET https://api.infrai.cc/v1/email/get/ID \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 4) email.suppression.add
curl -X POST https://api.infrai.cc/v1/email/suppression/add \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
# 5) email.domain.verify
curl -X POST https://api.infrai.cc/v1/email/domain/verify \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"domain": "sample"}'
# 6) email.batch.send
curl -X POST https://api.infrai.cc/v1/email/batch/send \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messages": [{"to": "sample"}]}'
# 7) email.list
curl -X GET https://api.infrai.cc/v1/email/list \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 8) email.event.list
curl -X GET https://api.infrai.cc/v1/email/event/list \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 1) Auth: every call is a raw HTTPS request carrying only your project key.
# No SDK to install — just the `requests` library.
import os, requests
BASE = "https://api.infrai.cc"
HEADERS = {
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
"Content-Type": "application/json",
}
# 2) email.send
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/send",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'to': 'alice@example.com', 'subject': 'Welcome', 'html': '<p>Hi!</p>'},
)
resp.raise_for_status()
print(resp.json())
# 3) email.get
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/get/ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 4) email.suppression.add
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/suppression/add",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'email': 'user@example.com'},
)
resp.raise_for_status()
print(resp.json())
# 5) email.domain.verify
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/domain/verify",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'domain': 'sample'},
)
resp.raise_for_status()
print(resp.json())
# 6) email.batch.send
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/email/batch/send",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'messages': [{'to': 'sample'}]},
)
resp.raise_for_status()
print(resp.json())
# 7) email.list
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 8) email.event.list
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/email/event/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
// 1) Auth: every call is a raw HTTPS request carrying only your project key.
// No SDK to install — just the built-in fetch().
const BASE = "https://api.infrai.cc";
const HEADERS = {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
};
// 2) email.send
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"to": "alice@example.com", "subject": "Welcome", "html": "<p>Hi!</p>"}),
},
);
console.log(await resp.json());
// 3) email.get
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/get/ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 4) email.suppression.add
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/add",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"email": "user@example.com"}),
},
);
console.log(await resp.json());
// 5) email.domain.verify
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/verify",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"domain": "sample"}),
},
);
console.log(await resp.json());
// 6) email.batch.send
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/batch/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"messages": [{"to": "sample"}]}),
},
);
console.log(await resp.json());
// 7) email.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 8) email.event.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/event/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 1) Auth: every call is a raw HTTPS request carrying only your project key.
// No SDK to install — just the built-in fetch(), typed.
const BASE = "https://api.infrai.cc";
const HEADERS: Record<string, string> = {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
};
// 2) email.send
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"to": "alice@example.com", "subject": "Welcome", "html": "<p>Hi!</p>"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 3) email.get
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/get/ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 4) email.suppression.add
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/suppression/add",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"email": "user@example.com"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 5) email.domain.verify
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/domain/verify",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"domain": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 6) email.batch.send
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/batch/send",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"messages": [{"to": "sample"}]}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 7) email.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 8) email.event.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/email/event/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);