Transactional email with templates, domain verification and delivery tracking.
1. Overview
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. Methods (17)
2.1email.send
Send a transactional email; supports templates and attachments.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
to | string | string[] | Required | Recipient address or list of addresses. |
subject | string | Required | Subject line. |
text | string | Optional | Plain-text body. |
html | string | Optional | HTML body. |
from | string | Optional | Sender address (requires a verified domain). |
cc | string[] | Optional | Carbon-copy addresses. |
bcc | string[] | Optional | Blind carbon-copy addresses. |
template_id | string | Optional | Template id to render instead of a body. |
template_vars | Record<string, unknown> | Optional | Variables passed to the template. |
attachments | Array<{ filename, content, mime? }> | Optional | Files to attach. |
vendor | string | Optional | Pin a specific vendor instead of auto-routing. |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
EmailRecord { email_id, state, to, subject, vendor, created_at }| Name | Type | Description |
|---|---|---|
message_id | string | Unique identifier for this messagepattern: ^msg_[A-Za-z0-9]{20,}$ |
vendor_message_id | string | null | Message identifier assigned by the upstream vendor |
from_used | string | Sender email address that was actually used for delivery |
mode | "default_vendor" | "verified_domain" | Delivery mode or operation mode |
scheduled_at | string | null | ISO 8601 timestamp when the resource is scheduled to activateformat: date-time |
accepted_recipients | string[] | List of recipient email addresses that were accepted |
suppressed_recipients | string[] | List of recipient email addresses that were suppressed |
metadata | object | null | Cost/vendor disclosure for this send (cost-transparency contract surface). A superset of kernel ResultMetadata that also carries the email-specific `mode` field; present once a vendor route has been resolved (absent only if all recipients were pre-suppressed before delivery was attempted... still normally present with cost_usd=0 in that case). |
metadata.request_id | string | UUID v7. |
metadata.trace_id | string | Distributed tracing identifier |
metadata.timestamp | string | Unix timestamp of the data pointformat: date-time |
metadata.latency_ms | integer | Latency of the operation in milliseconds≥ 0 |
metadata.entry_form | any | Entry point format (rest, mcp, sdk) |
metadata.cost_usd | number | Cost of this operation in USD≥ 0 |
metadata.cost_cny | number | Cost in CNY for this request≥ 0 |
metadata.vendor | string | Adapter name; references VendorRegistry. |
metadata.vendor_region | "china" | "western" | Vendor region where the request was processed |
metadata.markup_pct | number | Markup percentage applied on top of vendor cost |
metadata.mode | "default_vendor" | "verified_domain" | Email delivery mode this send resolved to (email-specific field not present on the generic kernel ResultMetadata). |
Example
一次性前置(每个范例都假定已完成):
# 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
Fetch a single email record by id.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The email record id. |
Returns
EmailRecord| Name | Type | Description |
|---|---|---|
message_id | string | Archive id of the message (msg_ + hex).pattern: ^msg_[A-Za-z0-9]{12,}$ |
state | string | Aggregate state — see enums/email_state.yaml. |
channel | "email" | Delivery channel of the archived record. |
to | any | Recipient(s) the message was sent to (string or array, as submitted). |
vendor | string | Serving vendor that dispatched the message. |
created_at | number | string | Epoch seconds (or ISO-8601) when the message was archived. |
per_recipient_state | object | OPTIONAL — map of recipient_email -> per-recipient state (populated only when a delivery-event webhook pipeline is wired). |
first_event_at | string | OPTIONAL — first delivery-event timestamp (webhook-derived).format: date-time |
last_event_at | string | OPTIONAL — latest delivery-event timestamp (webhook-derived).format: date-time |
counts | object | OPTIONAL — per-event-type tallies (delivered/bounced/opened/clicked/...), webhook-derived. |
Example
一次性前置(每个范例都假定已完成):
# 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
Add an address to the suppression list.
Returns
SuppressionRecord| Name | Type | Description |
|---|---|---|
email | string | Email addressformat: email |
reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | Reason for the current state or action |
added_at | string | ISO 8601 timestamp when this resource was addedformat: date-time |
last_attempt_at | string | null | Last time a send was blocked by this entry.format: date-time |
attempt_count_blocked | integer | null | Number of delivery attempts blocked by this suppression≥ 0 |
notes | string | null | Free-text notes about this suppression |
scope | "account" | "domain" | Scope of applicability for this resource |
domain_scope | string | null | When scope=domain, the specific verified domain. |
Example
一次性前置(每个范例都假定已完成):
# 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
Verify a sending domain and return required DNS records.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | The domain to verify. |
Returns
{ verified, records: Array<{ type, name, value }> }| Name | Type | Description |
|---|---|---|
domain | string | Apex domain, e.g. 'yourdomain.com'. |
domain_id | string | Unique identifier for this domainpattern: ^dom_[A-Za-z0-9]{20,}$ |
status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | Current status of this resource |
dns_records | object[] | DNS records required for domain verification |
dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | Type discriminator for this resource |
dns_records[].name | string | Fully qualified DNS name. |
dns_records[].value | string | Value of the DNS record or configuration |
dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | Purpose of the DNS record |
dns_records[].ttl_recommended | integer | Recommended TTL in seconds≥ 60default: 3600 |
checks | object | null | Per-record check status ('ok'/'pending'/'mismatch'/...). |
warm_up_state | "not_started" | "in_progress" | "complete" | null | Current warm-up state for the domain |
daily_limit_current | integer | null | Current daily sending limit≥ 0 |
daily_limit_target | integer | null | Target daily sending limit after warm-up≥ 0 |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
verified_at | string | null | ISO 8601 timestamp when verification was completedformat: date-time |
expires_at | string | null | DKIM rotation due (1y recommended).format: date-time |
rotated | boolean | Present only on the response of email.domain.rotate_dkim: true once the DKIM key rotation has been issued (status drops back to pending_dns until the new record is observed in DNS). |
Example
一次性前置(每个范例都假定已完成):
# 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(批量直通,单条不重复计费)。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
messages | EmailSendOptions[] | Required | 邮件数组,每项是一个完整的 EmailSendRequest,各自带收件人与模板变量,1 到 100 条。1–100 items |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
BatchSendResult { batch_id, results }| Name | Type | Description |
|---|---|---|
batch_id | string | Unique identifier for this batch jobpattern: ^batch_[A-Za-z0-9]{20,}$ |
results | object[] | List of individual results from a batch operation |
results[].index | integer | Position of this message in the request messages[] array.≥ 0 |
results[].message_id | string | null | Null when this message failed to enqueue.pattern: ^msg_[A-Za-z0-9]{20,}$ |
results[].to | string | string[] | - |
results[].status | "accepted" | "suppressed" | "failed" | - |
results[].error | string | null | Error code when status=failed (e.g. SUPPRESSED_RECIPIENT). |
Example
一次性前置(每个范例都假定已完成):
# 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
List the event timeline for one email.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
message_id | string | Required | Required. The message_id whose event timeline should be queried. |
type | string | Optional | 按事件类型过滤(如 delivered、bounced、opened)。 |
limit | number | Optional | Maximum items to return. |
cursor | string | Optional | Pagination cursor. |
Returns
{ items: EmailEvent[], next_cursor? }| Name | Type | Description |
|---|---|---|
items | object[] | List of resource records |
items[].type | "queued" | "sent" | "delivered" | "opened" | "clicked" | "bounced" | "complained" | "deferred" | "expired" | "cancelled" | "unsubscribed" | "auto_suppressed" | Type discriminator for this resource |
items[].at | string | ISO 8601 timestamp of the eventformat: date-time |
items[].recipient | string | Recipient email addressformat: email |
items[].message_id | string | null | Unique identifier for this messagepattern: ^msg_[A-Za-z0-9]{20,}$ |
items[].meta | object | null | Event-specific metadata (ip / user_agent / url / bounce_type / reason). |
count | integer | Number of items in this page≥ 0 |
next_cursor | string | null | Pass back into event.list() to fetch the next page. |
Example
一次性前置(每个范例都假定已完成):
# 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
查询某个收件地址是否在抑制名单中。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
email | string | Required | 收件邮箱地址。 |
Returns
SuppressionCheckResult { is_suppressed, record? }| Name | Type | Description |
|---|---|---|
email | string | The email address that was checked. |
suppressed | boolean | Whether the address is currently suppressed |
reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | Reason for the current suppression. Present only when suppressed=true. |
added_at | string | ISO 8601 timestamp when this suppression was added. Present only when suppressed=true.format: date-time |
last_attempt_at | string | null | Last time a send was blocked by this entry. Present only when suppressed=true.format: date-time |
attempt_count_blocked | integer | null | Number of delivery attempts blocked by this suppression. Present only when suppressed=true.≥ 0 |
notes | string | null | Free-text notes about this suppression. Present only when suppressed=true. |
scope | "account" | "domain" | Scope of applicability for this suppression entry. Present only when suppressed=true. |
domain_scope | string | null | When scope=domain, the specific verified domain. Present only when suppressed=true. |
Example
一次性前置(每个范例都假定已完成):
# 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
列出抑制名单中的收件地址。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
reason | string | Optional | 按抑制原因过滤(如 bounce、complaint、manual)。 |
limit | number | Optional | Maximum items to return. |
cursor | string | Optional | Pagination cursor. |
Returns
{ items: SuppressionRecord[], next_cursor? }| Name | Type | Description |
|---|---|---|
items | object[] | List of resource records |
items[].email | string | Email addressformat: email |
items[].reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | Reason for the current state or action |
items[].added_at | string | ISO 8601 timestamp when this resource was addedformat: date-time |
items[].last_attempt_at | string | null | Last time a send was blocked by this entry.format: date-time |
items[].attempt_count_blocked | integer | null | Number of delivery attempts blocked by this suppression≥ 0 |
items[].notes | string | null | Free-text notes about this suppression |
items[].scope | "account" | "domain" | Scope of applicability for this resource |
items[].domain_scope | string | null | When scope=domain, the specific verified domain. |
count | integer | Number of items in this page≥ 0 |
next_cursor | string | null | Opaque cursor to fetch the next page; null/absent if this is the last page |
Example
一次性前置(每个范例都假定已完成):
# 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
将某地址移出抑制名单,恢复对其投递。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
email | string | Required | 收件邮箱地址。 |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
{ deleted: boolean }| Name | Type | Description |
|---|---|---|
email | string | null | Email address removed from suppression list |
deleted | boolean | Whether the suppression entry was removed (same value as `found`: the entry existed and was removed from the suppression store). |
found | boolean | Whether a suppression entry existed for this email prior to the delete call. |
Example
一次性前置(每个范例都假定已完成):
# 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
列出账户下已添加的发信域名。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | number | Optional | Maximum items to return. |
cursor | string | Optional | Pagination cursor. |
Returns
{ items: DomainVerification[], next_cursor? }| Name | Type | Description |
|---|---|---|
records | object[] | List of resource records |
records[].domain | string | Apex domain, e.g. 'yourdomain.com'. |
records[].domain_id | string | Unique identifier for this domainpattern: ^dom_[A-Za-z0-9]{20,}$ |
records[].status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | Current status of this resource |
records[].dns_records | object[] | DNS records required for domain verification |
records[].dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | Type discriminator for this resource |
records[].dns_records[].name | string | Fully qualified DNS name. |
records[].dns_records[].value | string | Value of the DNS record or configuration |
records[].dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | Purpose of the DNS record |
records[].dns_records[].ttl_recommended | integer | Recommended TTL in seconds≥ 60default: 3600 |
records[].checks | object | null | Per-record check status ('ok'/'pending'/'mismatch'/...). |
records[].warm_up_state | "not_started" | "in_progress" | "complete" | null | Current warm-up state for the domain |
records[].daily_limit_current | integer | null | Current daily sending limit≥ 0 |
records[].daily_limit_target | integer | null | Target daily sending limit after warm-up≥ 0 |
records[].created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
records[].verified_at | string | null | ISO 8601 timestamp when verification was completedformat: date-time |
records[].expires_at | string | null | DKIM rotation due (1y recommended).format: date-time |
records[].rotated | boolean | Present only on the response of email.domain.rotate_dkim: true once the DKIM key rotation has been issued (status drops back to pending_dns until the new record is observed in DNS). |
total_count | integer | Total number of items across all pages≥ 0 |
next_cursor | string | null | Pass back into domain.list() to fetch the next page. |
Example
一次性前置(每个范例都假定已完成):
# 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
获取某个发信域名的验证状态与信誉信息。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | The domain to verify. |
Returns
DomainGetResult { verification, reputation }| Name | Type | Description |
|---|---|---|
verification | object | Domain verification status and DNS records |
verification.domain | string | Apex domain, e.g. 'yourdomain.com'. |
verification.domain_id | string | Unique identifier for this domainpattern: ^dom_[A-Za-z0-9]{20,}$ |
verification.status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | Current status of this resource |
verification.dns_records | object[] | DNS records required for domain verification |
verification.dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | Type discriminator for this resource |
verification.dns_records[].name | string | Fully qualified DNS name. |
verification.dns_records[].value | string | Value of the DNS record or configuration |
verification.dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | Purpose of the DNS record |
verification.dns_records[].ttl_recommended | integer | Recommended TTL in seconds≥ 60default: 3600 |
verification.checks | object | null | Per-record check status ('ok'/'pending'/'mismatch'/...). |
verification.warm_up_state | "not_started" | "in_progress" | "complete" | null | Current warm-up state for the domain |
verification.daily_limit_current | integer | null | Current daily sending limit≥ 0 |
verification.daily_limit_target | integer | null | Target daily sending limit after warm-up≥ 0 |
verification.created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
verification.verified_at | string | null | ISO 8601 timestamp when verification was completedformat: date-time |
verification.expires_at | string | null | DKIM rotation due (1y recommended).format: date-time |
verification.rotated | boolean | Present only on the response of email.domain.rotate_dkim: true once the DKIM key rotation has been issued (status drops back to pending_dns until the new record is observed in DNS). |
reputation | object | null | Null until the domain is verified and has begun warming up. |
reputation.domain | string | Domain name |
reputation.tier | "warming_up" | "established" | "trusted" | "throttled" | "suspended" | Current subscription tier (standard / pro / enterprise) |
reputation.current_daily_cap | integer | Current daily sending cap≥ 0 |
reputation.used_today | integer | Number of emails sent today≥ 0 |
reputation.bounce_rate_30d | number | Bounce rate over the last 30 days0–1 |
reputation.complaint_rate_30d | number | Complaint rate over the last 30 days0–1 |
reputation.days_in_current_tier | integer | Days in the current warm-up tier≥ 0 |
reputation.next_tier | "warming_up" | "established" | "trusted" | "throttled" | "suspended" | null | Next warm-up tier |
reputation.next_tier_requirements | object | null | Concrete thresholds + remaining-duration to upgrade. |
reputation.throttle_risk | "low" | "medium" | "high" | Current risk of being throttled based on recent domain reputation metrics. |
Example
一次性前置(每个范例都假定已完成):
# 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
删除一个已添加的发信域名。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | The domain to verify. |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
{ deleted: boolean }| Name | Type | Description |
|---|---|---|
domain | string | null | Domain name that was deleted |
deleted | boolean | Whether the domain was deleted (same value as `found`: the domain existed and was removed from the self-managed sender-domain store). |
found | boolean | Whether a domain verification record existed for this domain prior to the delete call. |
Example
一次性前置(每个范例都假定已完成):
# 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 记录。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | The domain to verify. |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
DomainVerification { domain, status, dns_records, ... }| Name | Type | Description |
|---|---|---|
domain | string | Apex domain, e.g. 'yourdomain.com'. |
domain_id | string | Unique identifier for this domainpattern: ^dom_[A-Za-z0-9]{20,}$ |
status | "pending_dns" | "verifying" | "verified" | "failed" | "expired" | Current status of this resource |
dns_records | object[] | DNS records required for domain verification |
dns_records[].type | "TXT" | "CNAME" | "MX" | "A" | "AAAA" | Type discriminator for this resource |
dns_records[].name | string | Fully qualified DNS name. |
dns_records[].value | string | Value of the DNS record or configuration |
dns_records[].purpose | "spf" | "dkim" | "tracking" | "dmarc" | "return_path" | "verification" | Purpose of the DNS record |
dns_records[].ttl_recommended | integer | Recommended TTL in seconds≥ 60default: 3600 |
checks | object | null | Per-record check status ('ok'/'pending'/'mismatch'/...). |
warm_up_state | "not_started" | "in_progress" | "complete" | null | Current warm-up state for the domain |
daily_limit_current | integer | null | Current daily sending limit≥ 0 |
daily_limit_target | integer | null | Target daily sending limit after warm-up≥ 0 |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
verified_at | string | null | ISO 8601 timestamp when verification was completedformat: date-time |
expires_at | string | null | DKIM rotation due (1y recommended).format: date-time |
rotated | boolean | Present only on the response of email.domain.rotate_dkim: true once the DKIM key rotation has been issued (status drops back to pending_dns until the new record is observed in DNS). |
Example
一次性前置(每个范例都假定已完成):
# 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
创建一个邮件模板。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Required | 模板名称,账户内唯一。1–128 chars |
subject | string | Required | 主题模板,可包含 {{var}} 占位符。 |
html | string | Required | HTML 正文模板,可包含 {{var}}、{{#section}}、{{^inverted}}。 |
body_text | string | Optional | 纯文本备用正文。 |
variables | Record<string, string> | Optional | 声明的变量及类型,如 { name: 'string' }。 |
default_vars | Record<string, unknown> | Optional | 发送时变量缺失所用的默认值。 |
tags | string[] | Optional | 模板标签列表。 |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
Template { template_id, name, subject, html, ... }| Name | Type | Description |
|---|---|---|
template_id | string | Identifier of the template used for renderingpattern: ^tmpl_[A-Za-z0-9]{20,}$ |
name | string | Unique within account.1–128 chars |
subject | string | May contain double-brace placeholders (e.g. var). |
html | string | HTML body; may contain double-brace placeholders (var, #section, ^inverted). |
body_text | string | null | Plain-text alternative. |
variables | object | null | Declared variables: name with type 'string', 'int', 'bool', 'array', or 'object'. |
default_vars | object | null | Defaults used when var missing in send(). |
tags | string[] | null | Tags for categorization and filtering |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
updated_at | string | ISO 8601 timestamp when this resource was last updatedformat: date-time |
Example
一次性前置(每个范例都假定已完成):
# 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
更新一个已有的邮件模板。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Template id to render instead of a body. |
subject | string | Optional | 主题模板,可包含 {{var}} 占位符。 |
html | string | Optional | HTML 正文模板,可包含 {{var}}、{{#section}}、{{^inverted}}。 |
body_text | string | Optional | 纯文本备用正文。 |
variables | Record<string, string> | Optional | 声明的变量及类型,如 { name: 'string' }。 |
default_vars | Record<string, unknown> | Optional | 发送时变量缺失所用的默认值。 |
tags | string[] | Optional | 模板标签列表。 |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
Template { template_id, name, subject, html, ... }| Name | Type | Description |
|---|---|---|
template_id | string | Identifier of the template used for renderingpattern: ^tmpl_[A-Za-z0-9]{20,}$ |
name | string | Unique within account.1–128 chars |
subject | string | May contain double-brace placeholders (e.g. var). |
html | string | HTML body; may contain double-brace placeholders (var, #section, ^inverted). |
body_text | string | null | Plain-text alternative. |
variables | object | null | Declared variables: name with type 'string', 'int', 'bool', 'array', or 'object'. |
default_vars | object | null | Defaults used when var missing in send(). |
tags | string[] | null | Tags for categorization and filtering |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
updated_at | string | ISO 8601 timestamp when this resource was last updatedformat: date-time |
Example
一次性前置(每个范例都假定已完成):
# 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
删除一个邮件模板。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Template id to render instead of a body. |
idempotency_key | string | Optional | Optional dedup key; identical retries return the same result. |
Returns
{ deleted: boolean }| Name | Type | Description |
|---|---|---|
template_id | string | null | Identifier of the deleted template |
deleted | boolean | Whether the template was deleted (same value as `found`: the template existed and was removed from the template store). |
found | boolean | Whether a template existed with this id prior to the delete call. |
Example
一次性前置(每个范例都假定已完成):
# 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、文本及缺失变量。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Template id to render instead of a body. |
vars | Record<string, unknown> | Required | 用于渲染的变量值,会与模板的 default_vars 合并。 |
Returns
TemplatePreview { rendered_subject, rendered_html, rendered_text, missing_vars }| Name | Type | Description |
|---|---|---|
rendered_subject | string | Rendered subject line with variables substituted |
rendered_html | string | Rendered HTML body with variables substituted |
rendered_text | string | null | Rendered plain text body with variables substituted |
missing_vars | string[] | Variables referenced by template but missing from input + default_vars. |
Example
一次性前置(每个范例都假定已完成):
# 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(())
}Advanced: pin a vendor
By default infrai routes each call to the best available provider — you do not pick a vendor. As an escape hatch, this capability accepts an optional vendor parameter to pin one specific provider. Every live vendor for this capability is available in real time from the discovery endpoint for the capability id — see the discovery API.
GET /v1/discovery/{capability}email.send
3. All capabilities
Every routed capability in this module — the complete public REST contract. The methods above are the guided walkthrough; this index is the full reference.
email.batch.sendPOST /v1/email/batch/sendSend up to 100 personalized emails under one idempotency_key (batch passthrough, not billed per message).
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
messages | object[] | Required | Each entry is a full EmailSendRequest with its own recipients / template_vars.1–100 items |
idempotency_key | string | null | Optional | 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.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | Path parameter. |
email.domain.getGET /v1/email/domain/get/{domain}Get the verification status and reputation of a sender domain.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | Path parameter. |
email.domain.listGET /v1/email/domain/listList the sender domains added to the account.
No request parameters.
email.domain.rotate_dkimPOST /v1/email/domain/rotate_dkim/{domain}Rotate DKIM for a sender domain and return the new DNS records.
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | Path parameter. |
idempotency_key | string | null | Optional | 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.
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Required | Sending domain to verify (e.g. mail.example.com). |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
email.event.listGET /v1/email/event/listList email delivery events (delivered, bounced, opened, clicked, complained).
No request parameters.
email.getGET /v1/email/get/{id}Get the delivery details of one email by message_id.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter. |
email.sendPOST /v1/email/sendSend a transactional email (inline body/HTML or a template) with tracking; idempotent.
Parameters (21)
| Name | Type | Required | Description |
|---|---|---|---|
to | string | string[] | Required | Recipient address, or an array of addresses for multiple recipients. |
cc | string[] | Optional | Carbon copy recipients |
bcc | string[] | Optional | Blind carbon copy recipients |
from | string | null | Optional | 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 | Optional | Display name for the sender |
reply_to | string | null | Optional | Reply-to email address |
subject | string | null | Optional | Email subject line |
body | string | null | Optional | Plain text body. |
html | string | null | Optional | HTML body of the email |
template_id | string | null | Optional | Identifier of the template used for rendering |
template_vars | object | null | Optional | Variables to substitute in the template |
attachments | object[] | Optional | List of email attachments |
headers | object | null | Optional | Custom HTTP headers to include in requests or responses |
tags | string[] | Optional | Tags for categorization and filtering |
track_opens | boolean | Optional | Whether to track email opensdefault: false |
track_clicks | boolean | Optional | Whether to track link clicks in the emaildefault: false |
scheduled_at | string | null | Optional | ISO 8601 timestamp when the resource is scheduled to activateformat: date-time |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
vendor | string | null | Optional | Pin to a specific vendor. |
message_class | "transactional" | "marketing" | Optional | Semantic class of the message. Only transactional is currently live; marketing is reserved and fails closed.default: "transactional" |
auto_unsubscribe_link | boolean | null | Optional | 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.
Parameters (6)
| Name | Type | Required | Description |
|---|---|---|---|
email | string | Required | Email addressformat: email |
reason | "hard_bounce" | "soft_bounce_5x" | "complained" | "unsubscribed" | "invalid" | "manual" | "user_request" | Optional | Reason for the current state or actiondefault: "manual" |
scope | "account" | "domain" | Optional | Scope of applicability for this resourcedefault: "account" |
domain_scope | string | null | Optional | When scope=domain, the specific verified domain. |
notes | string | null | Optional | Free-text notes about this suppression |
idempotency_key | string | null | Optional | 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.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
email | string | Required | Path parameter. |
email.suppression.deleteDELETE /v1/email/suppression/delete/{email}Remove an address from the suppression list to resume delivery.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
email | string | Required | Path parameter. |
email.suppression.listGET /v1/email/suppression/listList recipient addresses on the suppression list.
No request parameters.
email.template.createPOST /v1/email/template/createCreate an email template.
Parameters (8)
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Required | Unique within account.1–128 chars |
subject | string | Required | May contain double-brace var placeholders. |
html | string | Required | HTML body; may contain double-brace var, double-brace #section, double-brace ^inverted. |
body_text | string | null | Optional | Plain-text alternative. |
variables | object | null | Optional | Declared variables: { name: 'string' | 'int' | 'bool' | 'array' | 'object' }. |
default_vars | object | null | Optional | Defaults used when var missing in send(). |
tags | string[] | null | Optional | Tags for categorization and filtering |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
email.template.deleteDELETE /v1/email/template/delete/{id}Delete an email template.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter. |
email.template.previewPOST /v1/email/template/preview/{id}Render and preview a template with the given variables.
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter. |
vars | object | Required | Variable values merged with the template's default_vars before rendering. |
email.template.updatePATCH /v1/email/template/update/{id}Update an existing email template.
Parameters (8)
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter. |
subject | string | null | Optional | May contain double-brace var placeholders. |
html | string | null | Optional | HTML body; may contain double-brace var, double-brace #section, double-brace ^inverted. |
body_text | string | null | Optional | Plain-text alternative. |
variables | object | null | Optional | Template variable definitions |
default_vars | object | null | Optional | Default variable values for the template |
tags | string[] | null | Optional | Tags for categorization and filtering |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
4. End-to-end example
A production-style walkthrough of this module: configure once, then run the flow. It exercises most of the module's APIs.
A copy-paste-runnable single-file Python program (stdlib only, no SDK): set your INFRAI_API_KEY, run it, and walk this module's core flow with REAL billed calls — later steps reuse real fields returned by earlier ones. The 12-line helper is the entire integration.
#!/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}))
# 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 email delivery events (delivered, bounced, opened, clicked, complained).
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": "sample"}'
# 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.event.list
curl -X GET https://api.infrai.cc/v1/email/event/list \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 8) email.suppression.check
curl -X GET https://api.infrai.cc/v1/email/suppression/check/EMAIL \
-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': 'sample'},
)
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.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())
# 8) email.suppression.check
# 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())
// 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": "sample"}),
},
);
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.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());
// 8) email.suppression.check
// 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());
// 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": "sample"}),
},
);
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.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);
// 8) email.suppression.check
// 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);