> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up a custom notification-email identity for a sub-account

> Configure the from-name and from-address that system notification emails use for a subaccount, verify the sending domain with DKIM and SPF, and read the fallback chain that picks the parent or platform sender.

# Set up a custom notification-email identity for a sub-account

System notification emails (balance alerts, rate sheets, digests, invites) sent on behalf of a subaccount leave from the platform sender by default. A custom notification-email identity replaces that `From` line with your own name and address, for example `Acme Corp Notifications <notifications@acme.com>`, so the mail your child org's users receive carries your brand instead of the platform's.

This guide covers setting the identity in the dashboard and over the API, verifying the sending domain, and reading the fallback chain that decides which address an email actually leaves from.

Two settings are easy to confuse:

| Setting | Controls | Guide |
| - | - | - |
| Notification sender | The `From` name and address on notification emails | This page |
| Notification recipients | Which inboxes receive rate-sheet and balance-alert emails | [Sub-account notification recipients](/guides/subaccounts-notification-recipients) |

## Why resellers set this up

If you operate Orbit as a white-label platform, your subaccounts' users should never see the platform's domain in their inbox. When Orbit sends a low-balance alert for the child org "Acme Retail", the default `From` is the platform identity. With a verified custom identity, the same email arrives as `From: Acme Corp Notifications <notifications@acme.com>`.

The identity applies to system notification emails only. Campaign senders, per-message reply-to, and digest cadence are separate controls; see [What this does not change](#what-this-does-not-change).

## Prerequisites

* A provisioned subaccount. If you have not created one yet, follow [White-label subaccounts](/guides/subaccounts-reseller).
* The **admin** role on the parent organization, or admin/owner on the subaccount itself when you configure the subaccount's own identity.
* A sending domain you control, with access to its DNS records.
* The domain added as a sender identity. Verification happens on the Email senders surface; [Sender identity onboarding](/guides/sender-identity-onboarding-map) covers adding the domain and reading its DNS records.

## Set the identity in the dashboard

1. Open **Settings > Sub-accounts** and select the subaccount.
2. In the **Notification email sender** panel, fill in:
   * **From name**: the display name recipients see, for example `Acme Corp Notifications`. Leave blank to inherit the parent or platform display name.
   * **From address**: the address emails leave from, for example `notifications@acme.com`. Leave blank for "no override, inherit".
3. Choose **Save changes**.

The panel then shows two readouts that tell you what will actually send.

**Verification badge.** With a from-address set, the panel shows either **Verified** or **Pending verification**:

* **Verified** means the address's domain has passed DKIM and SPF for this org. Notification emails now leave from this address.
* **Pending verification** means the address is saved but not active yet. Emails use the fallback sender until the domain verifies. The fallback is silent by design: Orbit never sends from a domain that has not passed DKIM and SPF, because such mail hard-fails at the gateway.

**Effective sender.** When no address is set, the panel prints the sender currently in use, for example "Currently inheriting the parent's sender: [reseller@parent.com](mailto:reseller@parent.com)" or "Currently sending from the platform default: [noreply@orbit.devotel.io](mailto:noreply@orbit.devotel.io)". The API exposes the same readout as the `effective` block described below.

## Verify the domain (DKIM and SPF)

Verification is per sending domain and reuses the evidence the Email senders surface tracks. The notification-email panel saves your address and reports the outcome; the DNS records themselves come from Email senders.

1. Save the from-address in the notification-email panel. The badge shows **Pending verification**.
2. Open **Email senders** and add the from-address's domain if it is not listed yet. The surface shows the exact DKIM and SPF records to create.
3. Add those records as TXT entries at your DNS provider.
4. Re-check verification on Email senders. Propagation depends on your provider's TTL; fresh records typically take minutes, occasionally hours.
5. Reload the subaccount page. The badge flips to **Verified**, and `GET /subaccounts/{id}/notification-email` now returns `"verified": true`.

Until step 5 succeeds, emails go out from the nearest verified sender up the chain, never from the pending domain.

## The fallback chain

Resolution walks the org chain (the subaccount, then each parent, up to eight levels deep) and picks the first org whose configured from-address sits on a DNS-verified domain for that org. If no org in the chain qualifies, the platform default sends.

| Subaccount configuration | What sends | `effective.source` |
| - | - | - |
| Address set, domain verified | The subaccount's own address | `subaccount` |
| Address set, domain not verified | Nearest ancestor with a verified sender, else the platform default | `ancestor` or `platform` |
| No address set | Nearest ancestor with a verified sender, else the platform default | `ancestor` or `platform` |
| Address cleared (`null` or blank) | Same as not set; previous behavior | `ancestor` or `platform` |

Two response fields make the outcome explicit:

* `effective.source`: one of `subaccount`, `ancestor`, `platform`.
* `effective.resolved_from_organization_id`: the organization whose verified identity won; `null` when the platform default sends.

If an email left from an address you did not expect, read these two fields first: `source: "ancestor"` means the subaccount's own domain was not verified at send time, and `resolved_from_organization_id` names the org that supplied the sender.

## API recipe

Both endpoints require the admin role: a parent-org admin for any child, or the subaccount's own admin when `{id}` is the caller's own organization.

### Read the current configuration

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/subaccounts/org_child123/notification-email \
  -H "Authorization: Bearer $ORBIT_TOKEN"
```

```json theme={null}
{
  "data": {
    "from_name": "Acme Corp Notifications",
    "from_address": "notifications@acme.com",
    "verified": true,
    "effective": {
      "from_address": "notifications@acme.com",
      "from_name": "Acme Corp Notifications",
      "source": "subaccount",
      "resolved_from_organization_id": "org_child123"
    }
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-10-13T09:00:00.000Z"
  }
}
```

When the subaccount inherits instead, `effective` names the real sender:

```json theme={null}
{
  "data": {
    "from_name": null,
    "from_address": null,
    "verified": false,
    "effective": {
      "from_address": "reseller@parent.com",
      "from_name": "Parent Reseller",
      "source": "ancestor",
      "resolved_from_organization_id": "org_parent456"
    }
  },
  "meta": {
    "request_id": "req_def456",
    "timestamp": "2026-10-13T09:00:00.000Z"
  }
}
```

### Set the identity

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/subaccounts/org_child123/notification-email \
  -H "Authorization: Bearer $ORBIT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from_name": "Acme Corp Notifications",
    "from_address": "notifications@acme.com"
  }'
```

The response has the same shape as the GET. Right after saving an unverified domain, `verified` is `false` while `effective` still reports the fallback sender; once the domain verifies, `effective.source` moves to `subaccount` without another PUT.

### Clear the override

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/subaccounts/org_child123/notification-email \
  -H "Authorization: Bearer $ORBIT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "from_address": null }'
```

Sending `from_address: null` (or an empty string) clears the override, and the org inherits from its parent or the platform default. Clearing the address clears the from-name with it.

## Validation rules

* `from_address` must be a well-formed `local@domain` address of at most 254 characters; anything else returns 422.
* `from_name` is at most 128 characters; blank or `null` means "no display name".
* The request body accepts exactly `from_name` and `from_address`; unknown fields return 422.
* Saving does not require verification. Verification gates activation, not storage, so you can configure the identity first and verify the domain afterwards.

## Gotchas

* **The platform domain is not a valid custom identity.** You can save an address on `orbit.devotel.io`, but the platform domain is never in an org's verified-sender list, so it cannot verify and resolution falls back. Use a domain you own.
* **Unverified reads like unset at send time.** Both states fall back to the chain. If a co-branded email showed the parent sender, check the badge or the `verified` flag first.
* **Parent and subaccount on different verified domains.** Each domain carries its own DKIM and SPF records, and recipient-side DMARC alignment is evaluated against the domain that actually sends. After a fallback, the aligned domain is the one in `effective.from_address`, not the one you configured.
* **DKIM rotation.** When you rotate the DNS records of a sending domain, re-run verification from Email senders. Until the domain re-verifies, subaccounts on it fall back to the chain.
* **Verification is evaluated per org.** Resolution checks each org's configured address against that org's own verified senders as it walks the chain.

## What this does not change

The notification-email identity routes the sender only:

* **Who receives** rate sheets and balance alerts per subaccount: [Sub-account notification recipients](/guides/subaccounts-notification-recipients).
* **How often** digests and notifications send: [Digest and notification channels FAQ](/guides/digest-and-notification-channels-faq).
* **Campaign sender identities**, which are managed per campaign and are not affected by this setting.
* **Per-message reply-to overrides**, which this setting does not touch.
* **Email content.** The identity changes the `From` line only; the panel does not expose template or body editing.

## Confirm it worked

There is no send-test button for notification emails; the reliable check is the API plus the next real email:

1. Call `GET /subaccounts/{id}/notification-email` and confirm `effective.source` is `subaccount` with your address in `effective.from_address`. This is the authoritative readout of what the next email will use.
2. Trigger a real notification: transfer credits out of the subaccount to trip the low-balance alert, or wait for the next scheduled digest (cadences are in the [FAQ](/guides/digest-and-notification-channels-faq)).
3. In the inbox that receives it (per the [recipients configuration](/guides/subaccounts-notification-recipients) for this subaccount), confirm the `From` line shows your name and address.

Notification emails carry no per-subaccount marker header today; the `effective` block is the supported way to confirm which org's identity a send used.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.