# Delete profile

> Erases a profile's personal data and cancels its scheduled emails. Use it to fulfil a
> right-to-erasure request.
>
> Identify the profile by any combination of `external_profile_id`, `customer_user_id`, and
> `email` — Adapty Mail resolves the profile the same way it does on save.
>
> Erasure is final. A later [Save profile](#operation/saveProfile) request carrying the same
> identifiers doesn't recreate the profile.
>
> Repeat a deletion by `external_profile_id` or `customer_user_id` and it succeeds again
> without changing anything. Repeat one that carried only `email` and it returns `404`:
> erasure clears the stored address, so an email has nothing left to match.

## OpenAPI

```yaml
/api-specs/adapty-mail-api.yaml post /api/v1/profile/delete/
openapi: 3.1.0
info:
  title: Adapty Mail API
  version: 1.0.0
  description: |
    The Adapty Mail API lets you send user profiles and transaction events to Adapty Mail directly
    from your server, without routing the data through the Adapty SDK.

    Use it to:

    - Add subscribers when you don't have a base in Adapty Mail yet.
    - Reuse the subscriber base from your other apps.
    - Feed Adapty Mail server-to-server, with your backend as the source of truth.

    A profile with an email is enough for the **never purchased** flow. Every other flow
    (renewal cancelled, billing issue, expired, refunded) is driven by purchase history, so those
    profiles also need transaction events to be placed in the right flow.

    For a step-by-step walkthrough, see [Send emails and transactions via the Adapty Mail API](/docs/mail-send-data-via-api).
servers:
  - url: https://api-mail.adapty.io
    description: Production server
paths:
  /api/v1/profile/delete/:
    post:
      summary: Delete profile
      description: |
        Erases a profile's personal data and cancels its scheduled emails. Use it to fulfil a
        right-to-erasure request.

        Identify the profile by any combination of `external_profile_id`, `customer_user_id`, and
        `email` — Adapty Mail resolves the profile the same way it does on save.

        Erasure is final. A later [Save profile](#operation/saveProfile) request carrying the same
        identifiers doesn't recreate the profile.

        Repeat a deletion by `external_profile_id` or `customer_user_id` and it succeeds again
        without changing anything. Repeat one that carried only `email` and it returns `404`:
        erasure clears the stored address, so an email has nothing left to match.
      operationId: deleteProfile
      security:
        - apikeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProfileDeleteDTO"
            examples:
              byExternalProfileId:
                summary: Delete by the identifier you sent when saving the profile
                value:
                  external_profile_id: user_12345
              byEmail:
                summary: Delete by email address
                value:
                  email: jane@example.com
      responses:
        "204":
          description: Profile deleted. The response has no body.
        "400":
          description: No identifier was provided.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Errors"
              examples:
                default:
                  value:
                    errors:
                      - message: At least one of external_profile_id, customer_user_id or email must be provided
                        error_code: missing_identifier
                        status_code: 400
                        field_name: null
        "403":
          description: Missing or invalid secret API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Errors"
              examples:
                default:
                  value:
                    errors:
                      - message: Secret key doesn't exist
                        error_code: secret_key_does_not_exist_error
                        status_code: 403
                        field_name: null
        "404":
          description: No profile matches the identifiers you sent.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Errors"
              examples:
                default:
                  value:
                    errors:
                      - message: Profile not found
                        error_code: profile_not_found_error
                        status_code: 404
                        field_name: null
components:
  schemas:
    ProfileDeleteDTO:
      type: object
      description: |
        Identifiers for the profile to erase. Send at least one of `external_profile_id`,
        `customer_user_id`, or `email`.
      anyOf:
        - required:
            - external_profile_id
        - required:
            - customer_user_id
        - required:
            - email
      properties:
        external_profile_id:
          type: string
          description: The identifier you sent when saving the profile.
        customer_user_id:
          type: string
          description: The user's identifier in your own system.
        email:
          type: string
          format: email
          description: The email address on the profile.
    Errors:
      type: object
      description: Standard error response. Every failure returns a 4XX status with this shape.
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
                description: Human-readable description of the error.
              error_code:
                type: string
                description: Machine-readable error identifier.
              status_code:
                type: integer
                description: HTTP status code for this error.
              field_name:
                type: string
                description: The request field that caused the error, or `null` if the error isn't field-specific.
  securitySchemes:
    apikeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: |
        Authenticate every request with your Adapty Mail secret API key, sent as the **Authorization**
        header with the value `Bearer {your_secret_api_key}`, for example, `Bearer secret_live_...`.

        Find this key in Adapty Mail under **Settings**. The key is project-specific — it identifies the
        project the data belongs to, so the profile and transaction endpoints don't take a project ID.
```
