Provider adapters
An email provider adapter is the code that talks to one sending provider: it sends mail, verifies and normalizes the provider’s webhooks, and declares what the provider can do. ReputeCast’s core never calls a provider directly. It finds adapters in a registry and uses them through one contract, so routing, failover, Send Readiness, auto-pause and the shared suppression list work the same way for every provider.
How adapters work
Section titled “How adapters work”- Registration. Every adapter registers under a key, with a descriptor: its name, capabilities, the provider’s terms and the connection form. Built-in adapters use short keys (
ses,postmark); installed adapters usecommunity:<id>. Every ReputeCast process re-reads the installed adapters every 15 seconds. - Catalog. The setup catalog, the connect wizard and Sending providers, then Adapters read the registry, so a new adapter appears in all three.
- Connection. A workspace admin connects a provider through an adapter from Sending providers, then Add provider. Its credentials are sealed at rest and never returned.
- Sending. The sending engine renders and personalizes each message, then hands the adapter up to its batch size at a time. The adapter returns one result per message.
- Events. The provider posts webhooks to
/hooks/<adapter key>/<token>. ReputeCast verifies each request through the adapter before storing it, then the adapter maps it to normalized events. Hard bounces and complaints go on the shared suppression list. - Health. The health job checks each provider’s credentials or quota through the adapter. Repeated failures mark the provider down, and routing fails over per stream (see provider health and outages).

Three kinds of adapters
Section titled “Three kinds of adapters”| Kind | Runs as | Written by | Registry key | Installed with |
|---|---|---|---|---|
| Built-in | Go code inside the ReputeCast binary, tested against the shared contract suite | HostRepute and contributors, released with ReputeCast | ses, postmark, mailgun, … |
Every release |
| Generic HTTP | A JSON mapping of one provider’s HTTP API, run inside the binary | Any instance admin, without code | httpgeneric, or community:<name> once saved |
The form on the Adapters tab, or a manifest of kind http |
| Community | Its own process, in any language (TypeScript with the SDK) | Anyone | community:<id> |
reputecast adapter install, or Install from registry |
Built-in adapters exist for Amazon SES, Postmark, Postal, Mailgun, SendGrid, Resend, SparkPost, Mailjet, Brevo, Azure Communication Services and any SMTP server; choose a sending provider compares them. Every installed community adapter shows its version, maintainer, the capabilities its manifest declares and its update status. One without a release for a year is marked Unmaintained and is no longer offered for new connections.
What an adapter declares
Section titled “What an adapter declares”Each adapter states what the provider can do. These declarations become the badges in the catalog and on the routing screen:
- Bulk-marketing terms: allowed, Broadcast streams only, not allowed, or “your policy” for self-hosted servers and mapped APIs. Routing and Send Readiness use them.
- Webhooks: whether the provider reports deliveries, bounces and complaints. Without webhooks, ReputeCast gets no bounces or complaints from that provider (generic SMTP reads a bounce mailbox instead).
- Domain setup: through the provider’s API, or manual DNS records.
- Suppression sync: two-way, pull only, or local only. With local only, ReputeCast enforces the shared suppression list itself before sending.
- Batch size: how many distinct messages go in one API call.
- Sandbox, quota and rate discovery, dedicated IPs and pricing, and whether the provider tracks opens and clicks by default.
Choose an adapter
Section titled “Choose an adapter”- A built-in adapter exists for your provider: use it. Built-in adapters cover the provider’s domain, webhook and suppression APIs where they exist, and they are tested with every release.
- The provider takes one HTTP request per message and posts JSON webhooks with an HMAC signature, Standard Webhooks, basic auth or a secret header: map it with the generic HTTP adapter. A mapping sends one message per request, uses manual DNS and local-only suppressions, and has no quota discovery. The how-to is connect any HTTP email API.
- You need batches, a domain API, suppression sync, quota discovery, subscription handshakes or logic a mapping can’t express: write a community adapter. It runs in its own process, reaches only the hosts its manifest declares, and talks to ReputeCast over the signed adapter protocol.
- The provider should ship with ReputeCast for everyone: contribute a built-in adapter in Go.
Who does what
Section titled “Who does what”- The adapter author writes the adapter and publishes its image and
manifest.json. - The operator who runs the ReputeCast server runs the adapter process and tells ReputeCast where it listens, with its signing secret.
- An instance admin installs the adapter. Installed adapters apply to every workspace, so only instance admins can install, update or remove them.
- A workspace admin with
providers:manageconnects a provider through it, like any built-in adapter.
Defaults and limits
Section titled “Defaults and limits”These limits apply to community adapters that run in their own process:
| Setting | Default | How to change |
|---|---|---|
| Clock difference allowed on signed requests and answers | 5 minutes (300 s) | Fixed |
Previous signing secret keeps working after reputecast adapter secret | 24 hours | Fixed |
| Circuit breaker | Opens after 5 failures in a row; pauses 30 s, doubling up to 5 minutes while probes fail | Fixed |
| Calls at once per adapter | 64 | Fixed |
| Operation timeouts | health 5 s, verify 20 s, send 30 s, webhooks/verify 5 s, webhooks/parse 15 s, webhooks/register 30 s, domains 30 s, quota 20 s, suppressions 60 s | Fixed |
| Messages per send call | 1 unless the manifest declares 1–1,000 | capabilities.batch in manifest.json |
Largest manifest.json | 256 KiB | Fixed |
| Every process re-reads installed adapters | Every 15 s | Fixed |
| Adapter SDK remembers successful answers per idempotency key | 15 minutes | serve({ idempotencyTtlMs }) |
| Adapter flagged as unmaintained | 365 days after its manifest's last release; hidden from new connections | Fixed |
When to change them
Section titled “When to change them”- Declare
capabilities.batch(1 to 1,000) in the manifest when the provider’s API accepts several distinct, personalized messages in one call. - Turn on
providers.allow_private_networksonly when an adapter process or a mapped API runs on a loopback or private address, such as a sidecar container. Link-local and cloud metadata addresses stay refused. - The SDK remembers successful answers for 15 minutes (
serve({ idempotencyTtlMs })). The protocol requires at least 15 minutes, so don’t lower it.
Every other limit is fixed.
Related
Section titled “Related”- Generic HTTP adapter reference lists every field of a mapping.
- Write a community adapter builds, tests and installs an adapter from the template.
- Adapter protocol v1 is the wire reference for community adapters.
- Contribute a built-in adapter covers the Go contract and the contract suite.
- Supported services lists every provider ReputeCast works with.