# Connect Resend

An account of Resend is connected once, on the instance, by a person who then gives missions access to its resources; the agent never receives the credential. Outbound email : transactional sends classified by recipient zone, segments and contacts, broadcast campaigns, sending domains — one resource per domain and per segment.

One account is one Resend API key; resources are its sending domains and its contact segments. Sends are told apart by who the email goes to (internal, allow-listed, anyone), and the owner of the account labels each domain and segment with an environment so that staging and production are held separately.

Permissions, presets and tools of this service: [Resend plugin](/plugins/resend).

## How to connect

On the instance: Accounts → Connect an account, then pick the service. A company app, when the service needs one, is registered once by an administrator under Settings → Administration → Company apps, or set in the configuration (`providers.<id>.*`, see [configuration keys](/docs/configuration/keys)). Every instance registers its own app: this gateway never uses an app shared with another one.

### The usual way: with a key pasted by hand

Where: [https://resend.com/api-keys](https://resend.com/api-keys)

What the connect page asks:

- API key (secret): A key with "Full access" : resource discovery lists the domains and segments, which a "Sending access" key cannot read. Recipient zones are configured per domain resource after connection.

## Disconnecting

Delete the API key in the Resend dashboard, under API Keys.

## Registration notes from the plugin

From the plugin's [README](https://github.com/vaubaan/gateway/blob/main/plugins/resend/README.md), written for the people who register the app or create the token.

### Credential and resources

Kind `api-key`, one secret field:

| Field     | Pattern               | Purpose                                                        |
| --------- | --------------------- | -------------------------------------------------------------- |
| `api_key` | `^re_[A-Za-z0-9_-]+$` | A **Full access** key created at `https://resend.com/api-keys` |

There is no company-registered app for Resend: the owner creates the key in
the Resend dashboard and pastes it. A **Sending access** key cannot list
domains or segments, so discovery refuses it (`UpstreamAuthError`).

`discoverResources` pages through `GET /domains` and `GET /segments` (100 per
page, at most 500 per kind) and returns:

```ts
{ provider: 'resend', ref: 'notifications.acme.com', displayName: 'notifications.acme.com',
  metadata: { kind: 'domain', domain_id: 'd91c…', status: 'verified', region: 'eu-west-1',
              internal_domains: [], allowlist_domains: [], allowlist_addresses: [] } }
{ provider: 'resend', ref: '7826…', displayName: 'Newsletter',
  metadata: { kind: 'segment', segment_id: '7826…' } }
```

The **recipient zones** of a domain live in its resource metadata and start
empty, which is the safe default: until the owner fills them, every
recipient is `external-unbounded`. The owner edits the three lists (exact
domain or address match, case-insensitive) and labels the environment of
each resource. A host that re-runs discovery must preserve those edits.
