Skip to content
Norbelys
Esc
↑↓navigate↵open⌘Jpreview
On this page

Connect delivery providers

Connect Mailgun, SendGrid, Amazon SES or a private SMTP collector with credentials owned by your workspace.

Create a provider connection through POST /v1/integrations, using the same Clerk session or workspace API key as other resources. A browser can use this API; provider credentials are submitted once and stored encrypted. Customers do not edit server environment variables.

This resource manages delivery notifications. Mailboxes hold SMTP or native Gmail/Graph sending credentials. Adding a Mailgun, SendGrid or SES notification connection does not add a new native sending transport.

Mailgun

Use real mailbox IDs from your workspace and an API key allowed to read the account’s webhook signing key and manage domain webhooks. A sending-only key is insufficient.

{
  "name": "Production delivery",
  "mailbox_ids": ["mbx_01950000000070008000000000000001"],
  "connection": {
    "Mailgun": {
      "api_key": "REPLACE_WITH_YOUR_PROVIDER_API_KEY",
      "domain": "mail.example.com",
      "region": "Us"
    }
  }
}

The response includes id, provider, mailbox_ids, callback_url, status and timestamps. It never includes your key. Setup happens in the existing worker. Norbelys registers missing event callbacks while preserving other URLs. If a webhook type has no capacity, setup fails without replacing someone else’s callback. Use Eu for an EU account.

The domain must already exist in your Mailgun account. DNS verification, account approval and sending limits remain with the provider. This operation does not request Cloudflare credentials or modify DNS.

SendGrid

Use the same POST with this connection value:

{
  "Sendgrid": {
    "api_key": "REPLACE_WITH_YOUR_PROVIDER_API_KEY",
    "region": "Us"
  }
}

The key needs Event Webhook management permissions. Norbelys discovers its callback by URL, creates it disabled when missing, enables signatures, saves the verification key, then enables delivery events. Other webhooks remain unchanged. Available webhook capacity depends on your SendGrid plan. Eu selects the EU regional API.

Keep a dedicated provider account/subaccount or domain stream for each workspace. The connection accepts only messages from its configured mailbox IDs. Sending events for unrelated applications or other workspaces to this callback can produce correlation failures and provider retries.

Amazon SES

Use {"Ses":{"topic_arn":"arn:aws:sns:us-east-1:123456789012:mail-events"}} as the connection value. Create a dedicated SNS Standard topic, restrict publishing to the expected SES account, set SignatureVersion 2 and subscribe the returned callback_url over HTTPS with raw delivery disabled. The verified subscription confirmation is handled automatically. Creating AWS topics, IAM policies and event destinations remains an AWS account operation.

Enable original SES message headers: correlation uses mail.headers.Message-ID, not SES’s rewritten identifier. Configure a subscription dead-letter queue and monitor delivery errors. SHA-1/SNS signature version 1 is not accepted.

Private SMTP service

The optional Norbelys adapter connects the separately installed private SMTP product. Self-hosting the open-source campaign app does not require that service.

{
  "name": "Private SMTP feedback",
  "mailbox_ids": ["mbx_01950000000070008000000000000001"],
  "connection": {
    "Norbelys": { "webhook_key": "REPLACE_WITH_A_RANDOM_CONNECTION_SECRET" }
  }
}

The private service operator registers the returned callback and this connection’s key in that service, with the authorized SMTP usernames. The open-source app never needs its administration key, Docker access, DKIM private keys or provisioning code. Each SMTP identity belongs to one callback connection. For another trusted normalized collector, use Relay instead of Norbelys.

The callback key is separate from your product API key and SMTP password. Use at least 32 random printable ASCII characters and transmit credentials over HTTPS. Do not put them in URLs or logs. Norbelys’s collector produces queue/delivery/bounce evidence; Postfix logs cannot establish complaints or unsubscribes.

Status, updates and revocation

GET /v1/integrations/{id} exposes:

Status Meaning
Pending Automatic setup has been scheduled.
Ready Managed setup completed, or an externally configured connection accepted its first verified callback. This is not proof of delivery or inbox placement.
AwaitingConfiguration Register the callback at the external service.
Failed Check sanitized status_detail, account permissions, region and capacity. The worker retries automatically.
Disabled Callback processing has been revoked locally.

Managed connections are checked hourly. Transient failures retry after a minute; permissions or rejected configuration after an hour. Provider rate limits can delay the next attempt. checked_at reports the last managed check or first verified externally configured callback; it is not a last-delivery timestamp.

Use PATCH /v1/integrations/{id} with a replacement connection to rotate credentials for the same provider/account. Omitted fields remain unchanged. Do not reuse a connection for a different provider account. mailbox_ids replaces the allowed set and must contain only your workspace’s IDs. Normal updates return 409 while remote setup is in progress; retry using Retry-After.

{ "enabled": false }

A disable-only update takes effect even during remote setup and revokes incoming processing. It does not remove callbacks or revoke keys at the remote provider. Remove the remote callback explicitly when retiring a connection. There is no individual DELETE operation in this version. Workspace deletion removes its stored credentials. Each workspace can store up to 128 connections, including disabled records, with up to 1,000 mailbox IDs each.

GET /v1/integrations?page_size=50&q=Production uses the usual cursor-paginated collection. Connections cannot choose a tenant or a callback URL: the server derives both. Authenticated provider callbacks remain separate from customer API operations and MCP tools. Results appear in message delivery and mailbox health.

For deployment and the private service boundary, see docs/architecture/provider-webhooks.md in the source repository. The installation sets API_PUBLIC_URL and its encryption key once; it does not configure a variable for each customer provider.

Was this page helpful?