Skip to main content
While the REST API is recommended for modern applications, Ark supports standard SMTP for tools and frameworks that require it. Change one configuration and start sending through Ark instantly.
When to use SMTP: Self-hosted applications (Listmonk, Coolify, Metabase), legacy systems, or any software with built-in SMTP support but no HTTP API options.

Connection Details

Quick Reference

SettingValue
Hostsmtp.arkhq.io
Port587 (STARTTLS)
UsernameYour credential (e.g., acme/production)
PasswordYour credential key
EncryptionSTARTTLS required

Alternative Port

SettingValue
Hostsmtp.arkhq.io
Port465 (Implicit TLS)
UsernameYour credential (e.g., acme/production)
PasswordYour credential key
EncryptionTLS from start

Get Your Credentials

1

Open the Credentials Page

Go to arkhq.io/org/credentials in your dashboard.
2

Create or Select a Credential

Each credential has a username (like acme/production) and a key (your password).
3

Copy the Values

Use the username as your SMTP username and the key as your SMTP password.
Never share your credential key. It provides full sending access to your account. Rotate keys immediately if compromised.

Port Selection

PortEncryptionBest For
587STARTTLSMost applications. Connection upgrades to TLS after EHLO.
465Implicit TLSOlder apps that don’t support STARTTLS. Encrypted from the start.
Which should I use? Start with port 587. Only use 465 if your application doesn’t support STARTTLS or you encounter connection issues.
Edit your config.toml:
[smtp]
host = "smtp.arkhq.io"
port = 587
auth_protocol = "login"
username = "your-org/production"
password = "your-credential-key"
tls_type = "STARTTLS"
max_conns = 10
Or via environment variables:
LISTMONK_smtp__host=smtp.arkhq.io
LISTMONK_smtp__port=587
LISTMONK_smtp__auth_protocol=login
LISTMONK_smtp__username=your-org/production
LISTMONK_smtp__password=your-credential-key
LISTMONK_smtp__tls_type=STARTTLS
In Settings → Transactional Email:
FieldValue
SMTP EnabledYes
SMTP Hostsmtp.arkhq.io
SMTP Port587
SMTP Usernameyour-org/production
SMTP Passwordyour-credential-key
EncryptionTLS
From Addressnoreply@yourdomain.com
In Admin → Email:
FieldValue
SMTP Hostsmtp.arkhq.io
SMTP Port587
SMTP SecurityTLS
SMTP Usernameyour-org/production
SMTP Passwordyour-credential-key
From Addressmetabase@yourdomain.com
In grafana.ini or via environment:
[smtp]
enabled = true
host = smtp.arkhq.io:587
user = your-org/production
password = your-credential-key
from_address = alerts@yourdomain.com
starttls_policy = MandatoryStartTLS
In /etc/gitlab/gitlab.rb:
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.arkhq.io"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "your-org/production"
gitlab_rails['smtp_password'] = "your-credential-key"
gitlab_rails['smtp_domain'] = "yourdomain.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
Then run gitlab-ctl reconfigure.
Using WP Mail SMTP plugin:
SettingValue
MailerOther SMTP
SMTP Hostsmtp.arkhq.io
EncryptionTLS
SMTP Port587
AuthenticationOn
Usernameyour-org/production
Passwordyour-credential-key
In your config.production.json:
{
  "mail": {
    "transport": "SMTP",
    "options": {
      "host": "smtp.arkhq.io",
      "port": 587,
      "secure": false,
      "auth": {
        "user": "your-org/production",
        "pass": "your-credential-key"
      }
    }
  }
}
In Settings → SMTP:
FieldValue
SMTP Hostsmtp.arkhq.io
SMTP Port587
SMTP Useryour-org/production
SMTP Passwordyour-credential-key
SMTP SSLfalse
SMTP Sendern8n@yourdomain.com

Framework Integration

Using Nodemailer:
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.arkhq.io',
  port: 587,
  secure: false, // true for 465, false for 587
  auth: {
    user: process.env.SMTP_USERNAME,
    pass: process.env.SMTP_PASSWORD,
  },
});

await transporter.sendMail({
  from: '"Your App" <noreply@yourdomain.com>',
  to: 'user@example.com',
  subject: 'Welcome!',
  text: 'Thanks for signing up.',
  html: '<p>Thanks for signing up.</p>',
});

Web Framework Configuration

# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: "smtp.arkhq.io",
  port: 587,
  user_name: ENV["SMTP_USERNAME"],
  password: ENV["SMTP_PASSWORD"],
  authentication: :plain,
  enable_starttls_auto: true
}

Environment Variables

For most deployments, set these environment variables:
SMTP_HOST=smtp.arkhq.io
SMTP_PORT=587
SMTP_USERNAME=your-org/production
SMTP_PASSWORD=your-credential-key
SMTP_FROM=noreply@yourdomain.com
Environment variable names vary by application. Check your app’s documentation for the exact names.

Testing Your Connection

Quick Test with swaks

swaks --to you@example.com \
  --from test@yourdomain.com \
  --server smtp.arkhq.io:587 \
  --auth LOGIN \
  --auth-user "your-org/production" \
  --auth-password "your-credential-key" \
  --tls \
  --header "Subject: SMTP Test" \
  --body "If you see this, SMTP is working!"

Test TLS Connection

openssl s_client -connect smtp.arkhq.io:587 -starttls smtp
You should see certificate information and 250 responses from the server.
Success! If you receive the test email, your SMTP configuration is working correctly.

SMTP vs REST API

FeatureSMTPREST API
Best forSelf-hosted apps, legacy systemsModern applications
SetupConfiguration changeSDK or HTTP client
TrackingAutomatic via ArkExplicit parameters
Batch sendingSequentialUp to 100 per request
TagVia X-Ark-Tag headerNative tag parameter
MetadataVia X-Ark-Metadata-* headersNative metadata object
AttachmentsStandard MIMEBase64 in JSON
Same features, different interface. Emails sent via SMTP appear in the same dashboard, trigger the same webhooks, and use the same tracking as REST API emails. The only difference is how you send them.

Adding Tags and Metadata via SMTP

Tag

Use the X-Ark-Tag header to add a tag to your email:
X-Ark-Tag: welcome-email
Each email can have one tag. Tags appear in your dashboard and webhook events for filtering and analytics.

Metadata

Add custom key-value metadata using X-Ark-Metadata-* headers. Each header becomes a metadata key:
X-Ark-Metadata-user_id: usr_123456
X-Ark-Metadata-order_id: ord_789012
X-Ark-Metadata-campaign: welcome_series
This metadata is returned in all webhook payloads, allowing you to correlate email events with your internal systems. Validation Rules:
  • Maximum 10 metadata keys per email
  • Keys: 1-40 characters, must start with a letter, only alphanumeric and underscores
  • Values: 1-500 characters, no control characters (newlines, tabs, etc.)
  • Total size: 4KB maximum
SMTP is lenient with metadata. Invalid keys are silently skipped rather than rejecting the email. Valid metadata keys are preserved. This differs from the REST API, which returns an error for invalid metadata since you can fix and retry the request.
Example with Nodemailer:
await transporter.sendMail({
  from: '"Your App" <noreply@yourdomain.com>',
  to: 'user@example.com',
  subject: 'Order Confirmed',
  html: '<p>Your order has been confirmed.</p>',
  headers: {
    'X-Ark-Tag': 'order-confirmation',
    'X-Ark-Metadata-user_id': 'usr_123456',
    'X-Ark-Metadata-order_id': 'ord_789012',
  },
});
Example with Python smtplib:
msg = MIMEMultipart("alternative")
msg["Subject"] = "Order Confirmed"
msg["From"] = "Your App <noreply@yourdomain.com>"
msg["To"] = "user@example.com"
msg["X-Ark-Tag"] = "order-confirmation"
msg["X-Ark-Metadata-user_id"] = "usr_123456"
msg["X-Ark-Metadata-order_id"] = "ord_789012"
Example with Rails ActionMailer:
class OrderMailer < ApplicationMailer
  def confirmation(user, order)
    headers["X-Ark-Tag"] = "order-confirmation"
    headers["X-Ark-Metadata-user_id"] = user.id.to_s
    headers["X-Ark-Metadata-order_id"] = order.id.to_s

    mail(
      to: user.email,
      subject: "Order ##{order.id} confirmed"
    )
  end
end

Billing

SMTP sends are billed the same as REST API sends — included in your plan’s email quota. Your account status is checked when you send each message.

SMTP Response Codes

CodeMeaning
250 OKMessage accepted
452 Send limit exceededPlan email limit reached — upgrade your plan
452 Billing not configuredSet up billing in your dashboard
Account checked at send time: Ark checks your plan status when accepting each SMTP message. If your email limit is reached, the message is rejected immediately with a 452 response.

Example SMTP Session

S: 220 smtp.arkhq.io ESMTP
C: EHLO client.example.com
S: 250-smtp.arkhq.io Hello
S: 250 AUTH PLAIN LOGIN
C: AUTH PLAIN <credentials>
S: 235 Authentication successful
C: MAIL FROM:<sender@yourdomain.com>
S: 250 OK
C: RCPT TO:<recipient@example.com>
S: 250 OK
C: DATA
S: 354 Start mail input
C: Subject: Test
C: .
S: 250 OK                     # Success
# OR
S: 452 Send limit exceeded     # Plan limit reached
Fail-open design: If the billing system is temporarily unavailable, SMTP messages are accepted rather than rejected. This ensures your emails aren’t blocked by transient billing issues.

Troubleshooting

Cause: Your plan’s email limit has been reached.Solutions:
  • Check your usage at arkhq.io/org/billing
  • Upgrade to a higher plan for more email volume
  • Wait for your next billing cycle to reset the limit
Causes:
  • Firewall blocking outbound port 587/465
  • Cloud provider restricting SMTP (common on AWS, GCP, Azure)
Solutions:
  • Check firewall rules allow outbound 587/465
  • For AWS: Request SMTP sending limits removal
  • For GCP: Use port 587, not 25
  • Try port 465 if 587 is blocked
Causes:
  • Wrong username format
  • Incorrect password
  • Suspended credential
Solutions:
  • Username format is org-name/credential-name (check dashboard)
  • Use the credential key, not the credential ID
  • Verify credential is active in dashboard
Causes:
  • Outdated CA certificates on your system
  • Application doesn’t support modern TLS
Solutions:
  • Update system CA certificates
  • Try port 465 (implicit TLS) instead of 587 (STARTTLS)
  • Check your app supports TLS 1.2+
Causes:
  • Network latency
  • DNS resolution issues
  • SMTP traffic inspection/filtering
Solutions:
  • Increase client timeout settings
  • Verify DNS resolves smtp.arkhq.io correctly
  • Check for corporate proxies or firewalls inspecting SMTP
Causes:
  • Domain not verified
  • Recipient on suppression list
  • Email marked as spam
Solutions:
  • Verify your sending domain in the dashboard
  • Check suppressions
  • Review email content for spam triggers
  • Check recipient’s spam folder

Next Steps