# GET /api/twilio/email-log

Lists email-log rows for the caller's scope, newest first, with cursor-based paging.

Returns a page of outbound-email and SendGrid event records. All query filters
(recipient email, event types, correlation id, message id, timestamp range) are optional
and combined with AND. Tenant and merchant scoping is enforced server-side from the
caller's operating context: merchant-scoped users see only their own merchant, while a
caller holding `EmailLog.ViewAllMerchants` may target a specific merchant via
`MerchantId` or leave the scope open.


Paging is keyset / cursor-based, not skip/take. Pass `NextContinuationToken` from the
previous response back as `ContinuationToken` to fetch the next page; a `null`
token in the response means there are no further pages. Sorting supports
`Timestamp ASC` / `Timestamp DESC` only and defaults to descending.

**Operation ID:** `GET_api_twilio_email-log`

## Authorization

Requires: Twilio.EmailLog.View, merchant scope.

Required permissions:
- `Twilio.EmailLog.View`

## Parameters

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| MaxResultCount | query | no | integer(int32) | Maximum rows per page. The app service caps this at 100. |
| ContinuationToken | query | no | string | Opaque cursor returned by a prior call. `null` for the first page. |
| IncludeDeleted | query | no | boolean | Disables the soft-delete filter. Honoured only for callers with the relevant permission. |
| IncludeInactive | query | no | boolean | Disables the IsActive filter. Honoured only for callers with the relevant permission. |
| Sorting | query | no | string | Sort direction. Only `Timestamp ASC` and `Timestamp DESC` are supported —  the cursor encodes (Timestamp, Id) for stable paging, so multi-field sorts would  require a richer cursor than this surface needs. Anything else falls back to  `Timestamp DESC`. |
| Filter | query | no | string | Optional substring match on PhoeniXGate.Twilio.EmailLog.EmailLogDto.Email. |
| Email | query | no | string | Optional exact-match recipient email. |
| EventTypes | query | no | array<string> | Optional event-type include list (e.g. `Delivered`, `GatewaySent`). |
| CorrelationId | query | no | string(uuid) | Optional correlation id (single outbound message lifecycle). |
| MessageId | query | no | string | Optional SendGrid message id (cross-partition lookup). |
| MinTimestamp | query | no | string(date-time) | Inclusive lower-bound timestamp filter. |
| MaxTimestamp | query | no | string(date-time) | Exclusive upper-bound timestamp filter. |
| MerchantId | query | no | string(uuid) | Caller-requested merchant scope. Honoured only when the caller has the  `EmailLog.ViewAllMerchants` permission; otherwise the app service substitutes  the operating-context merchant. Reseller-tree filtering ("see every merchant in my  reseller tree") is intentionally not supported on this surface yet — the  cross-module merchant lookup it requires is a follow-on capability. |
| suppressNulls | query | no | boolean | If true, omit properties with null values. |

## Responses

### 200

OK

**Content type:** `text/plain`

Schema: `PhoenixAbpCoreApplicationContractsContinuationPagedResultDtoOfPhoeniXGateTwilioEmailLogEmailLogDto`

**Content type:** `application/json`

Schema: `PhoenixAbpCoreApplicationContractsContinuationPagedResultDtoOfPhoeniXGateTwilioEmailLogEmailLogDto`

**Content type:** `text/json`

Schema: `PhoenixAbpCoreApplicationContractsContinuationPagedResultDtoOfPhoeniXGateTwilioEmailLogEmailLogDto`

### 403

Forbidden

**Content type:** `text/plain`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `text/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

### 401

Unauthorized

**Content type:** `text/plain`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `text/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

### 400

Bad Request

**Content type:** `text/plain`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `text/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

### 404

Not Found

**Content type:** `text/plain`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `text/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

### 501

Not Implemented

**Content type:** `text/plain`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `text/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

### 500

Internal Server Error

**Content type:** `text/plain`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

**Content type:** `text/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

### default

The request failed. The body carries the standard error envelope: a machine-readable `error.code`, a human-readable `error.message`, and `error.validationErrors` when the failure was a validation rejection. See the error-code reference in this document's description for the values `error.code` can take.

**Content type:** `application/json`

Schema: `WinkPGHttpRemoteServiceErrorResponse`

## See also

- [All documentation](https://docs.winkpg.io/llms.txt): the machine-readable index of every public page on this site.
