Use this file to discover all available pages before exploring further.
Ark provides official, fully-typed SDKs in four languages, plus an MCP server for AI assistants. All SDKs offer consistent behavior, complete API coverage, and excellent developer experience.
Every SDK includes complete type definitions. Python has full type hints, Node.js has TypeScript definitions, Ruby has Sorbet RBI files, and Go has native types.Your IDE will provide autocomplete, inline documentation, and catch errors before runtime.
Automatic Retries
SDKs automatically retry failed requests with exponential backoff for:
Connection errors
408 Request Timeout
409 Conflict
429 Rate Limit
5xx Server Errors
Default: 2 retries. Configurable per-client or per-request.
Configurable Timeouts
Default timeout is 60 seconds. Customize globally or per-request:
Install with pip install ark-email[aiohttp] for best async performance.
Node.js SDK is async by default. All methods return Promises:
// Already async!const email = await client.emails.send({...});// Or with .then()client.emails.send({...}).then(email => { console.log(email.data.id);});
Ruby SDK uses synchronous HTTP by default but is thread-safe:
# Thread-safe - use a single client instanceclient = ArkEmail::Client.new(api_key: ENV["ARK_API_KEY"])threads = 10.times.map do |i| Thread.new do client.emails.send_( from: "hello@yourdomain.com", to: ["user#{i}@example.com"], subject: "Thread #{i}", html: "<p>Hello from thread #{i}</p>" ) endendthreads.each(&:join)
Go is concurrent by default with goroutines:
var wg sync.WaitGroupfor i := 0; i < 10; i++ { wg.Add(1) go func(n int) { defer wg.Done() client.Emails.Send(ctx, ark.EmailSendParams{ From: "hello@yourdomain.com", To: []string{fmt.Sprintf("user%d@example.com", n)}, Subject: fmt.Sprintf("Goroutine %d", n), HTML: ark.String("<p>Hello from goroutine</p>"), }) }(i)}wg.Wait()
If you’re building a white-label email platform, every SDK supports tenant-scoped operations. Pass a tenant_id to send emails, manage domains, and configure webhooks on behalf of your customers:
Python
Node.js
Ruby
Go
# Send email on behalf of a tenantemail = client.emails.send( from_="hello@customer-domain.com", to=["user@example.com"], subject="Order Confirmed", html="<p>Your order has been confirmed.</p>", tenant_id="tenant_abc123")# Create a domain for a tenantdomain = client.domains.create( name="mail.customer-domain.com", tenant_id="tenant_abc123")
// Send email on behalf of a tenantconst email = await client.emails.send({ from: 'hello@customer-domain.com', to: ['user@example.com'], subject: 'Order Confirmed', html: '<p>Your order has been confirmed.</p>', tenantId: 'tenant_abc123',});// Create a domain for a tenantconst domain = await client.domains.create({ name: 'mail.customer-domain.com', tenantId: 'tenant_abc123',});
# Send email on behalf of a tenantemail = client.emails.send_( from: "hello@customer-domain.com", to: ["user@example.com"], subject: "Order Confirmed", html: "<p>Your order has been confirmed.</p>", tenant_id: "tenant_abc123")# Create a domain for a tenantdomain = client.domains.create( name: "mail.customer-domain.com", tenant_id: "tenant_abc123")
// Send email on behalf of a tenantemail, _ := client.Emails.Send(ctx, ark.EmailSendParams{ From: "hello@customer-domain.com", To: []string{"user@example.com"}, Subject: "Order Confirmed", HTML: ark.String("<p>Your order has been confirmed.</p>"), TenantID: ark.String("tenant_abc123"),})// Create a domain for a tenantdomain, _ := client.Domains.Create(ctx, ark.DomainCreateParams{ Name: "mail.customer-domain.com", TenantID: ark.String("tenant_abc123"),})
New to white-label? Start with the Architecture Overview to understand how Platform → Tenant → Domain → Email hierarchy works. Then see Tenant Management for full CRUD operations.