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

# Subscribers By External ID

> Get, update, or delete subscribers by your own external ID

Use external-ID routes when your app has a stable customer, account, or user ID. Prefer the query form because it supports external IDs that contain slashes.

For `GET`, email engagement stats and recent activity exclude detected email-security scanners and tracked brand assets by default.

## Request

<ParamField query="externalId" type="string" required>
  Customer-owned external ID. Required for `GET`, `PATCH`, and `DELETE
      /subscribers/external`.
</ParamField>

<ParamField path="externalId" type="string">
  Compatibility path form for external IDs that do not contain slashes.
</ParamField>

<ParamField query="includeMachineEngagement" type="boolean" default="false">
  Set to `true` on `GET` requests to include detected scanner, preview, and
  tracked asset open/click events in `emailStats` and recent activity.
</ParamField>

When machine engagement is included, open/click activity events include
`machine`, `engagementQuality`, and `classificationReasons` fields.

<ParamField body="email" type="string">
  New subscriber email when updating.
</ParamField>

<ParamField body="externalId" type="string">
  New external ID when updating.
</ParamField>

<ParamField body="firstName" type="string">
  Updated first name.
</ParamField>

<ParamField body="lastName" type="string">
  Updated last name.
</ParamField>

<ParamField body="status" type="string">
  Updated status: `active` or `unsubscribed`.
</ParamField>

<ParamField body="tags" type="array">
  Replacement tag list.
</ParamField>

<ParamField body="customAttributes" type="object">
  Custom attributes to update. By default this replaces the existing public
  custom-attribute map.
</ParamField>

<ParamField body="customAttributesStrategy" type="string" default="replace">
  How to apply `customAttributes`: `replace` replaces the existing public
  custom-attribute map, while `merge` overwrites only the provided keys and
  retains unspecified existing keys.
</ParamField>

```bash theme={null}
curl "https://api.sequenzy.com/api/v1/subscribers/external?externalId=user_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```bash theme={null}
curl -X PATCH "https://api.sequenzy.com/api/v1/subscribers/external?externalId=user_123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "anna@example.com", "customAttributesStrategy": "merge", "customAttributes": {"plan": "pro"}}'
```

```bash theme={null}
curl -X DELETE "https://api.sequenzy.com/api/v1/subscribers/external?externalId=user_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Responses

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "subscriber": {
      "id": "sub_abc123",
      "email": "anna@example.com",
      "externalId": "user_123",
      "status": "active",
      "tags": ["customer"],
      "customAttributes": {
        "plan": "pro"
      }
    }
  }
  ```

  ```json 200 theme={null}
  {
    "success": true,
    "deleted": true
  }
  ```

  ```json 400 theme={null}
  {
    "success": false,
    "error": "externalId is required"
  }
  ```

  ```json 401 theme={null}
  {
    "success": false,
    "error": "Unauthorized"
  }
  ```

  ```json 404 theme={null}
  {
    "success": false,
    "error": "Subscriber not found"
  }
  ```

  ```json 409 theme={null}
  {
    "success": false,
    "error": "Another subscriber already uses that email or externalId"
  }
  ```
</ResponseExample>
