Skip to content

Send through the SMTP relay

How-to guide
For:
Server operators, Workspace admins, Developers
Needs permission:
apikeys:managesensitive
In the app:
Instance admin, then Instance & updates, then SMTP relay

The SMTP relay lets apps that can’t call an HTTP API send SMTP relay transactional email through ReputeCast: they connect on port 587 (STARTTLS) or 465 (TLS), authenticate with a send-only credential, and the message goes through the workspace’s Transactional route, suppressions and message log. An instance admin turns it on once per instance; each workspace then creates its own credentials.

  • You are an instance admin, and you can change the server’s firewall and Docker Compose file.
  • A hostname for the relay, such as smtp.example.com, with an A/AAAA record pointing to the server. The instance’s public URL host is suggested.
  • In the workspace: apikeys:manage to create SMTP credentials, and a verified Transactional sender. The From address of every message must be a verified Transactional sender (see add sending domains and senders).
  • Processes with the web role run the relay listeners. If you split roles, see scale with web, ingest and worker roles.

ReputeCast listens on the relay ports inside the container, but Docker Compose only publishes what you list. The default deploy/docker-compose.yml publishes port 8080 only, so add the two relay ports to the app service yourself:

docker-compose.yml
services:
app:
ports:
- "${REPUTECAST_PORT:-8080}:8080"
- "587:587" # SMTP relay, STARTTLS
- "465:465" # SMTP relay, implicit TLS

Apply it with docker compose up -d, and open both ports in the server’s firewall. SMTP is not HTTP, so the relay ports go straight to the app, never through your reverse proxy. If you change the ports in the relay settings, publish those instead.

  1. Open Instance admin, then Instance & updates from the account menu and find the SMTP relay section.

  2. Set the Hostname, the STARTTLS port (587) and the TLS port (465). The two ports must differ.

  3. Choose the Certificate:

    • Let’s Encrypt: ReputeCast gets and renews the certificate itself. Let’s Encrypt validates the hostname over HTTP, so http://<hostname>/.well-known/acme-challenge/ must reach a ReputeCast web process, for example through your reverse proxy. Every web node shares the certificate.
    • Certificate and key files: upload a Certificate chain (PEM) and a Private key (PEM). The key is write-only: it is sealed and never shown again.
  4. Choose Turn on, then Run checks. ReputeCast checks that the hostname resolves, that both ports are reachable from the internet, and that the certificate is valid. Checks also run every 10 minutes; instance admins are told when a port stops answering.

  1. In the workspace, open Transactional, then Setup and choose Create SMTP credential.

  2. Name it after the app, choose Live or Test mode, and optionally limit the templates and categories it can send and when it expires. Test mode delivers only to workspace members and the test addresses you allow.

  3. Copy the password now: it is shown once. The username is the credential’s key ID; the password is its secret, which starts with rc_smtp_. The credential holds transactional:send only, and never more than you hold now: it stops authenticating when you leave the workspace, are deactivated or no longer hold transactional:send.

Transactional Setup: the HTTP API card, the keys that can send including an SMTP credential for the billing service, and the SMTP relay card showing On.
Setting Value
Host The relay hostname, such as smtp.example.com
Port 587 with STARTTLS, or 465 with TLS
Auth PLAIN or LOGIN
Username The credential’s key ID
Password The credential’s secret (rc_smtp_…)
From An address on a verified Transactional sender

Two optional headers tag the message in ReputeCast; the relay reads them and they are not passed on:

Optional headers
X-ReputeCast-Tags: invoice, eu
X-ReputeCast-Category: Billing

X-ReputeCast-Tags is comma-separated. X-ReputeCast-Category takes a category’s name or ID; without it, a credential limited to one category uses that one. A recipient who turned an Optional category off doesn’t get its mail.

SettingDefaultHow to change
Ports587 (STARTTLS) and 465 (TLS)Instance admin › Instance & updates › SMTP relay; any two different ports
Largest message40 MiBFixed; the route's provider limit may be lower
Recipients per message50Fixed; each recipient counts against the credential's send rate
Connection read and write timeout5 minutes eachFixed
Status checksEvery 10 minutesRun the checks again
Settings changes reach other web processesWithin 30 sFixed

Send a message from your app, then open Transactional, then Messages. The message shows Raw (SMTP) in place of a template, with its delivery timeline.

  • The check says a port isn’t reachable → the port is not published in Compose, or a firewall in front of the server blocks it.
  • The check says the hostname doesn’t resolve → add the A/AAAA record, wait for DNS, then run the checks again.
  • Let’s Encrypt fails → port 80 for the hostname doesn’t reach a ReputeCast web process. Route /.well-known/acme-challenge/ to it, or upload certificate files.
  • Authentication fails → use the key ID as the username, not the credential’s name, and check that the credential isn’t revoked or expired, and that the member who created it is still active and holds transactional:send. The 535 reply says which.
  • The message is refused with a size error → the relay accepts up to 40 MiB, but the route’s sending providers may accept less; the reply says so.
  • Apps get a refused connection → the relay is off. The HTTP API keeps working either way.