# Sender

## Retrieve a sender

**get** `/v1/senders/{id}`

Retrieves a sender by its ID, archived ones included.

**[Required scope](/using-the-api/scopes/):** `senders:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sender to retrieve.

### Returns

- `SenderRetrieveResponse object { id, archivedAt, channel, 9 more }`

  - `id: string`

    Unique identifier of the sender.

  - `archivedAt: string`

    When the sender was archived, or null if it is active. Archived senders never send.

  - `channel: "EMAIL" or "LINKEDIN"`

    Whether this sender sends email or LinkedIn messages.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    When the sender was created.

  - `emailAddress: string`

    The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

  - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

    `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

    - `"UNVERIFIED"`

    - `"HEALTHY"`

    - `"UNHEALTHY"`

  - `healthReason: string`

    Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

  - `objectType: "sender"`

    Always `sender`.

    - `"sender"`

  - `owner: string`

    Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

  - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

    - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      Email steps. Present only on an email sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn connection requests. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn messages. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

  - `replyToAddress: string`

    SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

  - `transport: "SMTP" or "OAUTH"`

    How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

    - `"SMTP"`

    - `"OAUTH"`

### Example

```http
curl https://api.lightfield.app/v1/senders/$ID \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "archivedAt": "archivedAt",
  "channel": "EMAIL",
  "createdAt": "createdAt",
  "emailAddress": "emailAddress",
  "health": "UNVERIFIED",
  "healthReason": "healthReason",
  "objectType": "sender",
  "owner": "owner",
  "pacing": {
    "EMAIL": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    },
    "LINKEDIN_INVITE": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    },
    "LINKEDIN_MESSAGE": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    }
  },
  "replyToAddress": "replyToAddress",
  "transport": "SMTP"
}
```

## List senders

**get** `/v1/senders`

Returns a paginated list of the email and LinkedIn senders that sequences send from, archived ones included, ordered by `createdAt` descending. Use `offset` and `limit` to paginate, and bracketed filters to narrow the list.

Supported filters: `channel[equal]` (EMAIL, LINKEDIN), `health[equal]` (UNVERIFIED, HEALTHY, UNHEALTHY), `owner[equal]` (a member ID), and `archived[equal]` (true, false). Filters are combined with AND.

**[Required scope](/using-the-api/scopes/):** `senders:read`

**[Rate limit category](/using-the-api/rate-limits/):** Search

### Query Parameters

- `limit: optional number`

  Maximum number of records to return. Defaults to 25, maximum 25.

- `offset: optional number`

  Number of records to skip for pagination. Defaults to 0.

### Returns

- `SenderListResponse object { data, object, totalCount }`

  - `data: array of object { id, archivedAt, channel, 9 more }`

    - `id: string`

      Unique identifier of the sender.

    - `archivedAt: string`

      When the sender was archived, or null if it is active. Archived senders never send.

    - `channel: "EMAIL" or "LINKEDIN"`

      Whether this sender sends email or LinkedIn messages.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `createdAt: string`

      When the sender was created.

    - `emailAddress: string`

      The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

    - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

      `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

      - `"UNVERIFIED"`

      - `"HEALTHY"`

      - `"UNHEALTHY"`

    - `healthReason: string`

      Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

    - `owner: string`

      Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

      - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

        Email steps. Present only on an email sender.

        - `dailyLimit: number`

          Most sends of this step type in any rolling 24 hours.

        - `maxGapSeconds: number`

          Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

        - `minGapSeconds: number`

          Lower bound of the minimum spacing between two of its sends, in seconds.

      - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

        LinkedIn connection requests. Present only on a LinkedIn sender.

        - `dailyLimit: number`

          Most sends of this step type in any rolling 24 hours.

        - `maxGapSeconds: number`

          Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

        - `minGapSeconds: number`

          Lower bound of the minimum spacing between two of its sends, in seconds.

      - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

        LinkedIn messages. Present only on a LinkedIn sender.

        - `dailyLimit: number`

          Most sends of this step type in any rolling 24 hours.

        - `maxGapSeconds: number`

          Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

        - `minGapSeconds: number`

          Lower bound of the minimum spacing between two of its sends, in seconds.

    - `replyToAddress: string`

      SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

    - `transport: "SMTP" or "OAUTH"`

      How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

      - `"SMTP"`

      - `"OAUTH"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Example

```http
curl https://api.lightfield.app/v1/senders \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "id",
      "archivedAt": "archivedAt",
      "channel": "EMAIL",
      "createdAt": "createdAt",
      "emailAddress": "emailAddress",
      "health": "UNVERIFIED",
      "healthReason": "healthReason",
      "objectType": "sender",
      "owner": "owner",
      "pacing": {
        "EMAIL": {
          "dailyLimit": -9007199254740991,
          "maxGapSeconds": -9007199254740991,
          "minGapSeconds": -9007199254740991
        },
        "LINKEDIN_INVITE": {
          "dailyLimit": -9007199254740991,
          "maxGapSeconds": -9007199254740991,
          "minGapSeconds": -9007199254740991
        },
        "LINKEDIN_MESSAGE": {
          "dailyLimit": -9007199254740991,
          "maxGapSeconds": -9007199254740991,
          "minGapSeconds": -9007199254740991
        }
      },
      "replyToAddress": "replyToAddress",
      "transport": "SMTP"
    }
  ],
  "object": "list",
  "totalCount": -9007199254740991
}
```

## Update a sender

**post** `/v1/senders/{id}`

Replaces a sender's pacing and returns the updated sender. Send exactly the sender's step types, with every value: read the sender first to change only some of them. Concurrent updates are last-write-wins.

Each step type must stay within the ceilings the workspace's own limits have, and `maxGapSeconds` can't be below `minGapSeconds`: `EMAIL` on an OAuth sender `dailyLimit` at least 1 and gaps 60 to 3600 seconds; `EMAIL` on an SMTP sender `dailyLimit` 1 to 100 and gaps 60 to 3600 seconds; `LINKEDIN_INVITE` `dailyLimit` 1 to 30 and gaps 120 to 3600 seconds; `LINKEDIN_MESSAGE` `dailyLimit` 1 to 60 and gaps 120 to 3600 seconds. Out-of-range values, or step types the sender doesn't send, return 400.

Returns 409 if the sender is archived; archived senders can be read but not updated.

**[Required scope](/using-the-api/scopes/):** `senders:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sender to update.

### Body Parameters

- `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

  The sender's new pacing, replacing all of its current values. Send exactly the step types the sender's channel sends: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

  - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

    Email steps. Present only on an email sender.

    - `dailyLimit: number`

      Most sends of this step type in any rolling 24 hours.

    - `maxGapSeconds: number`

      Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

    - `minGapSeconds: number`

      Lower bound of the minimum spacing between two of its sends, in seconds.

  - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

    LinkedIn connection requests. Present only on a LinkedIn sender.

    - `dailyLimit: number`

      Most sends of this step type in any rolling 24 hours.

    - `maxGapSeconds: number`

      Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

    - `minGapSeconds: number`

      Lower bound of the minimum spacing between two of its sends, in seconds.

  - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

    LinkedIn messages. Present only on a LinkedIn sender.

    - `dailyLimit: number`

      Most sends of this step type in any rolling 24 hours.

    - `maxGapSeconds: number`

      Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

    - `minGapSeconds: number`

      Lower bound of the minimum spacing between two of its sends, in seconds.

### Returns

- `SenderUpdateResponse object { id, archivedAt, channel, 9 more }`

  - `id: string`

    Unique identifier of the sender.

  - `archivedAt: string`

    When the sender was archived, or null if it is active. Archived senders never send.

  - `channel: "EMAIL" or "LINKEDIN"`

    Whether this sender sends email or LinkedIn messages.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    When the sender was created.

  - `emailAddress: string`

    The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

  - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

    `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

    - `"UNVERIFIED"`

    - `"HEALTHY"`

    - `"UNHEALTHY"`

  - `healthReason: string`

    Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

  - `objectType: "sender"`

    Always `sender`.

    - `"sender"`

  - `owner: string`

    Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

  - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

    - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      Email steps. Present only on an email sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn connection requests. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn messages. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

  - `replyToAddress: string`

    SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

  - `transport: "SMTP" or "OAUTH"`

    How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

    - `"SMTP"`

    - `"OAUTH"`

### Example

```http
curl https://api.lightfield.app/v1/senders/$ID \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
          "pacing": {}
        }'
```

#### Response

```json
{
  "id": "id",
  "archivedAt": "archivedAt",
  "channel": "EMAIL",
  "createdAt": "createdAt",
  "emailAddress": "emailAddress",
  "health": "UNVERIFIED",
  "healthReason": "healthReason",
  "objectType": "sender",
  "owner": "owner",
  "pacing": {
    "EMAIL": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    },
    "LINKEDIN_INVITE": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    },
    "LINKEDIN_MESSAGE": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    }
  },
  "replyToAddress": "replyToAddress",
  "transport": "SMTP"
}
```

## Mark a sender healthy

**post** `/v1/senders/{id}/mark_healthy`

Clears a health reason that sending recorded, so the sender can be picked for new sends again, and returns the updated sender. A sender with nothing to clear is returned unchanged.

Clears `healthReason` `BOUNCE_THRESHOLD`, `RATE_LIMIT`, `INVITE_LIMIT` on an email sender, and `RATE_LIMIT`, `INVITE_LIMIT`, `UNKNOWN` on a LinkedIn sender. Clearing `BOUNCE_THRESHOLD` turns bounce protection off until hard bounces recur. Contacts the sender paused on their own resume once it can send again, unless another sender they are pinned to still cannot. Sequences an earlier LinkedIn limit deactivated stay deactivated until they are resumed.

Returns 409 for any other health reason, which clears only once its cause is fixed, for example reconnecting the account or fixing DNS; for an archived sender; or when the sender's health changed while the request ran.

**[Required scope](/using-the-api/scopes/):** `senders:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sender to mark healthy.

### Body Parameters

- `body: optional object {  }`

### Returns

- `SenderMarkHealthyResponse object { id, archivedAt, channel, 9 more }`

  - `id: string`

    Unique identifier of the sender.

  - `archivedAt: string`

    When the sender was archived, or null if it is active. Archived senders never send.

  - `channel: "EMAIL" or "LINKEDIN"`

    Whether this sender sends email or LinkedIn messages.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    When the sender was created.

  - `emailAddress: string`

    The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

  - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

    `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

    - `"UNVERIFIED"`

    - `"HEALTHY"`

    - `"UNHEALTHY"`

  - `healthReason: string`

    Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

  - `objectType: "sender"`

    Always `sender`.

    - `"sender"`

  - `owner: string`

    Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

  - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

    - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      Email steps. Present only on an email sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn connection requests. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn messages. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

  - `replyToAddress: string`

    SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

  - `transport: "SMTP" or "OAUTH"`

    How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

    - `"SMTP"`

    - `"OAUTH"`

### Example

```http
curl https://api.lightfield.app/v1/senders/$ID/mark_healthy \
    -X POST \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "archivedAt": "archivedAt",
  "channel": "EMAIL",
  "createdAt": "createdAt",
  "emailAddress": "emailAddress",
  "health": "UNVERIFIED",
  "healthReason": "healthReason",
  "objectType": "sender",
  "owner": "owner",
  "pacing": {
    "EMAIL": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    },
    "LINKEDIN_INVITE": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    },
    "LINKEDIN_MESSAGE": {
      "dailyLimit": -9007199254740991,
      "maxGapSeconds": -9007199254740991,
      "minGapSeconds": -9007199254740991
    }
  },
  "replyToAddress": "replyToAddress",
  "transport": "SMTP"
}
```

## Domain Types

### Sender List Response

- `SenderListResponse object { data, object, totalCount }`

  - `data: array of object { id, archivedAt, channel, 9 more }`

    - `id: string`

      Unique identifier of the sender.

    - `archivedAt: string`

      When the sender was archived, or null if it is active. Archived senders never send.

    - `channel: "EMAIL" or "LINKEDIN"`

      Whether this sender sends email or LinkedIn messages.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `createdAt: string`

      When the sender was created.

    - `emailAddress: string`

      The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

    - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

      `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

      - `"UNVERIFIED"`

      - `"HEALTHY"`

      - `"UNHEALTHY"`

    - `healthReason: string`

      Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

    - `owner: string`

      Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

      - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

        Email steps. Present only on an email sender.

        - `dailyLimit: number`

          Most sends of this step type in any rolling 24 hours.

        - `maxGapSeconds: number`

          Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

        - `minGapSeconds: number`

          Lower bound of the minimum spacing between two of its sends, in seconds.

      - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

        LinkedIn connection requests. Present only on a LinkedIn sender.

        - `dailyLimit: number`

          Most sends of this step type in any rolling 24 hours.

        - `maxGapSeconds: number`

          Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

        - `minGapSeconds: number`

          Lower bound of the minimum spacing between two of its sends, in seconds.

      - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

        LinkedIn messages. Present only on a LinkedIn sender.

        - `dailyLimit: number`

          Most sends of this step type in any rolling 24 hours.

        - `maxGapSeconds: number`

          Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

        - `minGapSeconds: number`

          Lower bound of the minimum spacing between two of its sends, in seconds.

    - `replyToAddress: string`

      SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

    - `transport: "SMTP" or "OAUTH"`

      How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

      - `"SMTP"`

      - `"OAUTH"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Sender Mark Healthy Response

- `SenderMarkHealthyResponse object { id, archivedAt, channel, 9 more }`

  - `id: string`

    Unique identifier of the sender.

  - `archivedAt: string`

    When the sender was archived, or null if it is active. Archived senders never send.

  - `channel: "EMAIL" or "LINKEDIN"`

    Whether this sender sends email or LinkedIn messages.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    When the sender was created.

  - `emailAddress: string`

    The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

  - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

    `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

    - `"UNVERIFIED"`

    - `"HEALTHY"`

    - `"UNHEALTHY"`

  - `healthReason: string`

    Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

  - `objectType: "sender"`

    Always `sender`.

    - `"sender"`

  - `owner: string`

    Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

  - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

    - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      Email steps. Present only on an email sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn connection requests. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn messages. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

  - `replyToAddress: string`

    SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

  - `transport: "SMTP" or "OAUTH"`

    How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

    - `"SMTP"`

    - `"OAUTH"`

### Sender Retrieve Response

- `SenderRetrieveResponse object { id, archivedAt, channel, 9 more }`

  - `id: string`

    Unique identifier of the sender.

  - `archivedAt: string`

    When the sender was archived, or null if it is active. Archived senders never send.

  - `channel: "EMAIL" or "LINKEDIN"`

    Whether this sender sends email or LinkedIn messages.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    When the sender was created.

  - `emailAddress: string`

    The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

  - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

    `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

    - `"UNVERIFIED"`

    - `"HEALTHY"`

    - `"UNHEALTHY"`

  - `healthReason: string`

    Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

  - `objectType: "sender"`

    Always `sender`.

    - `"sender"`

  - `owner: string`

    Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

  - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

    - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      Email steps. Present only on an email sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn connection requests. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn messages. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

  - `replyToAddress: string`

    SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

  - `transport: "SMTP" or "OAUTH"`

    How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

    - `"SMTP"`

    - `"OAUTH"`

### Sender Update Response

- `SenderUpdateResponse object { id, archivedAt, channel, 9 more }`

  - `id: string`

    Unique identifier of the sender.

  - `archivedAt: string`

    When the sender was archived, or null if it is active. Archived senders never send.

  - `channel: "EMAIL" or "LINKEDIN"`

    Whether this sender sends email or LinkedIn messages.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    When the sender was created.

  - `emailAddress: string`

    The address email from this sender is sent from. Null for LinkedIn senders, or when the connected account has no address.

  - `health: "UNVERIFIED" or "HEALTHY" or "UNHEALTHY"`

    `HEALTHY` can send. `UNHEALTHY` cannot send until `healthReason` is resolved. `UNVERIFIED` means no health verdict yet: an email sender in this state cannot send until it passes a health check, while a LinkedIn sender is never health-checked, so a working LinkedIn sender is usually `UNVERIFIED` and can send.

    - `"UNVERIFIED"`

    - `"HEALTHY"`

    - `"UNHEALTHY"`

  - `healthReason: string`

    Why the sender is `UNHEALTHY` or `UNVERIFIED`, for example `ACCOUNT_DISCONNECTED`, `BOUNCE_THRESHOLD` or `INVITE_LIMIT`; null when healthy.

  - `objectType: "sender"`

    Always `sender`.

    - `"sender"`

  - `owner: string`

    Member ID of the person who owns this sender, or null when no workspace membership can be resolved.

  - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How this sender paces each step type it sends, keyed by sequence step type: `EMAIL` for an email sender; `LINKEDIN_INVITE` and `LINKEDIN_MESSAGE` for a LinkedIn sender.

    - `EMAIL: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      Email steps. Present only on an email sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_INVITE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn connection requests. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit, maxGapSeconds, minGapSeconds }`

      LinkedIn messages. Present only on a LinkedIn sender.

      - `dailyLimit: number`

        Most sends of this step type in any rolling 24 hours.

      - `maxGapSeconds: number`

        Upper bound of the minimum spacing, in seconds. Before each send, a minimum spacing is drawn at random between `minGapSeconds` and this value, and the send waits until that long after the previous one. Sends can be further apart, for example outside the send window or once `dailyLimit` is reached. Null means the minimum spacing is always `minGapSeconds`.

      - `minGapSeconds: number`

        Lower bound of the minimum spacing between two of its sends, in seconds.

  - `replyToAddress: string`

    SMTP senders only: the connected mailbox replies are sent to and read from. Null for other senders.

  - `transport: "SMTP" or "OAUTH"`

    How an email sender sends: `SMTP` through its own mail server, `OAUTH` through its connected Google or Microsoft account. Null for LinkedIn senders.

    - `"SMTP"`

    - `"OAUTH"`
