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

# List Customer Emails

> Get every transactional email sent to a customer in the last 180 days, with its delivery outcome.



## OpenAPI

````yaml get /customers/{customer_id}/emails
openapi: 3.1.0
info:
  title: public
  description: ''
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
  version: 1.113.39
servers:
  - url: https://test.dodopayments.com/
    description: Test Mode Server Host
  - url: https://live.dodopayments.com/
    description: Live Mode Server Host
security: []
tags:
  - name: Products
  - name: Payments
  - name: Subscriptions
  - name: Addons
  - name: Customers
  - name: Refunds
  - name: Disputes
  - name: Events
  - name: License Keys
  - name: Entitlements
  - name: Licenses
  - name: Discounts
  - name: Meters
  - name: Credit Entitlements
  - name: Credit Entitlement Balances
  - name: Outgoing Webhooks
  - name: Checkout
  - name: Webhook Events
  - name: Payment Connector Webhooks
paths:
  /customers/{customer_id}/emails:
    get:
      tags:
        - Customers
      summary: List a customer's sent emails
      description: >-
        Returns every transactional email sent to this customer in the last 180

        days, newest first, with its delivery outcome. Delivery status comes
        from

        the email provider and is as fresh as replication, typically seconds.
      operationId: list_customer_emails_public
      parameters:
        - name: customer_id
          in: path
          description: The customer's id
          required: true
          schema:
            type: string
        - name: page_size
          in: query
          description: How many emails to return. The default is 10 and the maximum is 100.
          required: false
          schema:
            type: integer
            format: int32
            minimum: 0
          style: form
        - name: page_number
          in: query
          description: Which page to return. The default is 0.
          required: false
          schema:
            type: integer
            format: int32
            minimum: 0
          style: form
      responses:
        '200':
          description: The customer's sent emails
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListEmailLogsResponse'
        '422':
          description: Invalid Request Object or Parameters
        '500':
          description: Something went wrong :(
        '502':
          description: The email read model is unavailable
      security:
        - API_KEY: []
      x-codeSamples:
        - lang: JavaScript
          source: >-
            import DodoPayments from 'dodopayments';


            const client = new DodoPayments({
              bearerToken: process.env['DODO_PAYMENTS_API_KEY'], // This is the default and can be omitted
            });


            // Automatically fetches more pages as needed.

            for await (const emailLogItem of
            client.customers.emails.list('customer_id')) {
              console.log(emailLogItem.email_log_id);
            }
        - lang: Python
          source: |-
            import os
            from dodopayments import DodoPayments

            client = DodoPayments(
                bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),  # This is the default and can be omitted
            )
            page = client.customers.emails.list(
                customer_id="customer_id",
            )
            page = page.items[0]
            print(page.email_log_id)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/dodopayments/dodopayments-go\"\n\t\"github.com/dodopayments/dodopayments-go/option\"\n)\n\nfunc main() {\n\tclient := dodopayments.NewClient(\n\t\toption.WithBearerToken(\"My Bearer Token\"),\n\t)\n\tpage, err := client.Customers.Emails.List(\n\t\tcontext.TODO(),\n\t\t\"customer_id\",\n\t\tdodopayments.CustomerEmailListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n"
        - lang: Java
          source: |-
            package com.dodopayments.api.example;

            import com.dodopayments.api.client.DodoPaymentsClient;
            import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClient;
            import com.dodopayments.api.models.customers.emails.EmailListPage;
            import com.dodopayments.api.models.customers.emails.EmailListParams;

            public final class Main {
                private Main() {}

                public static void main(String[] args) {
                    DodoPaymentsClient client = DodoPaymentsOkHttpClient.fromEnv();

                    EmailListPage page = client.customers().emails().list("customer_id");
                }
            }
        - lang: Kotlin
          source: |-
            package com.dodopayments.api.example

            import com.dodopayments.api.client.DodoPaymentsClient
            import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClient
            import com.dodopayments.api.models.customers.emails.EmailListPage
            import com.dodopayments.api.models.customers.emails.EmailListParams

            fun main() {
                val client: DodoPaymentsClient = DodoPaymentsOkHttpClient.fromEnv()

                val page: EmailListPage = client.customers().emails().list("customer_id")
            }
        - lang: Ruby
          source: |-
            require "dodopayments"

            dodo_payments = Dodopayments::Client.new(
              bearer_token: "My Bearer Token",
              environment: "test_mode" # defaults to "live_mode"
            )

            page = dodo_payments.customers.emails.list("customer_id")

            puts(page)
        - lang: PHP
          source: |-
            <?php

            require_once dirname(__DIR__) . '/vendor/autoload.php';

            use Dodopayments\Client;
            use Dodopayments\Core\Exceptions\APIException;

            $client = new Client(
              bearerToken: getenv('DODO_PAYMENTS_API_KEY') ?: 'My Bearer Token',
              environment: 'test_mode',
            );

            try {
              $page = $client->customers->emails->list(
                'customer_id', pageNumber: 0, pageSize: 0
              );

              var_dump($page);
            } catch (APIException $e) {
              echo $e->getMessage();
            }
        - lang: C#
          source: |-
            using System;
            using DodoPayments.Client;
            using DodoPayments.Client.Models.Customers.Emails;

            DodoPaymentsClient client = new();

            EmailListParams parameters = new() { CustomerID = "customer_id" };

            var page = await client.Customers.Emails.List(parameters);
            await foreach (var item in page.Paginate())
            {
                Console.WriteLine(item);
            }
        - lang: Rust
          source: |-
            use dodopayments::Client;

            #[tokio::main]
            async fn main() -> dodopayments::Result<()> {
                let client = Client::from_env()?;
                let customer_id = "customer_id";
                let result = client
                    .customers()
                    .emails()
                    .list()
                    .customer_id(customer_id)
                    .query(serde_json::json!({}))
                    .await?;
                println!("{result:?}");
                Ok(())
            }
components:
  schemas:
    ListEmailLogsResponse:
      type: object
      required:
        - items
        - total_count
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/EmailLogItem'
          description: This page of emails, newest first.
        total_count:
          type: integer
          format: int64
          description: >-
            How many emails this customer has in the last 180 days, across
            pages.
          minimum: 0
    EmailLogItem:
      type: object
      required:
        - email_log_id
        - category
        - email_type
        - status
        - created_at
        - has_preview
        - policies
      properties:
        category:
          type: string
          description: |-
            The group this email belongs to: payments, refunds, subscriptions,
            dunning_recovery, entitlements or auth.
        created_at:
          type: string
          format: date-time
          description: When this email was sent.
        email_log_id:
          type: string
          description: Identifies this email. Use it to read the body or to send it again.
        email_type:
          type: string
          description: What kind of email this is, for example `payment_successful`.
        failure_code:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/EmailFailureCode'
              description: >-
                Why the email did not arrive. It is null unless the email
                failed.
        failure_reason:
          type:
            - string
            - 'null'
          description: |-
            A sentence that explains `failure_code`. It is null unless the email
            failed.
        from:
          type:
            - string
            - 'null'
          description: The address the email was sent from.
        has_preview:
          type: boolean
          description: >-
            Whether this email has content to show. The content endpoint can
            still

            refuse, because the content is removed after 180 days.
        policies:
          $ref: '#/components/schemas/EmailPolicies'
          description: What you may do with this email.
        recipient:
          type:
            - string
            - 'null'
          description: The address the email reached.
        status:
          $ref: '#/components/schemas/EmailLogStatus'
          description: >-
            Where the email got to: sent, delivered, failed, complained or
            blocked.
        subject:
          type:
            - string
            - 'null'
          description: >-
            The subject line as it was sent. Empty until the provider
            replicates.
    EmailFailureCode:
      type: string
      description: >-
        Why an email did not reach the recipient.


        The code is stable. `send_failed` is the catch-all: it covers every
        failure

        that the other codes do not name.
      enum:
        - mailbox_not_found
        - address_rejected
        - address_suppressed
        - mailbox_full
        - temporary_failure
        - message_too_large
        - marked_as_spam
        - send_failed
        - test_mode_quota_spent
    EmailPolicies:
      type: object
      description: >-
        What the merchant may do with one row. The server decides; the client
        never

        derives eligibility itself.
      required:
        - retry_allowed
        - resend_allowed
        - resends_remaining
        - requires_different_address
        - superseded
      properties:
        requires_different_address:
          type: boolean
          description: >-
            A permanent failure was recorded, so the same address would be a
            no-op.
        resend_allowed:
          type: boolean
          description: The row was delivered and may be sent again.
        resends_remaining:
          type: integer
          format: int64
          description: How many sends are left in this email's chain.
        retry_allowed:
          type: boolean
          description: The row failed and may be sent again.
        superseded:
          type: boolean
          description: >-
            A later send of this email reached the provider, so this row is
            history.

            To send it again would deliver a second copy.
    EmailLogStatus:
      type: string
      description: >-
        The delivery status of one email.


        `sent` also covers an email that is still on its way. A status only
        becomes

        `delivered`, `failed` or `complained` when the mail server answers.
      enum:
        - sent
        - delivered
        - failed
        - complained
        - blocked
  securitySchemes:
    API_KEY:
      type: http
      scheme: bearer

````