{
  "openapi": "3.0.3",
  "info": {
    "description": "The Bulk End-User Deletion API submits requests to erase all personal data associated with one or more end users across Ada's systems. A single request can carry up to 1000 identifiers, and each request is processed as an asynchronous job whose status can be polled. For access requirements, identifier types, dispositions, job lifecycle, and processing time, refer to the [Bulk End-User Deletion API Overview](/reference/bulk-end-user-deletion/overview).",
    "version": "1.0.0",
    "title": "Bulk End-User Deletion API"
  },
  "x-readme": {
    "explorer-enabled": false,
    "proxy-enabled": true
  },
  "servers": [
    {
      "url": "https://example.ada.support/api",
      "x-fern-server-name": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "parameters": {
      "JobId": {
        "name": "job_id",
        "description": "Identifier of the deletion job returned when the request was submitted.",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Platform API token passed as a bearer token.",
        "x-fern-bearer": {
          "name": "apiKey",
          "env": "ADA_API_KEY"
        }
      }
    },
    "schemas": {
      "DeletionIdentifierType": {
        "description": "The kind of identifier supplied. `variable_match` selects every end user whose stored variable equals the value.",
        "type": "string",
        "enum": [
          "email",
          "chatter_id",
          "external_id",
          "end_user_id",
          "variable_match"
        ],
        "example": "email"
      },
      "DeletionIdentifier": {
        "type": "object",
        "description": "A single reference to the end user(s) whose data should be erased.",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "$ref": "#/components/schemas/DeletionIdentifierType"
          },
          "value": {
            "description": "The identifier value. Email values are normalized and matched case-insensitively; `external_id` values are trimmed and lowercased at intake.",
            "type": "string",
            "example": "end-user@example.com"
          },
          "variable": {
            "description": "Name of the stored variable to match against `value`. Required only when `type` is `variable_match`; leave null for all other types.",
            "type": "string",
            "nullable": true,
            "example": null
          }
        }
      },
      "DeletionRequest": {
        "type": "object",
        "required": [
          "identifiers"
        ],
        "properties": {
          "identifiers": {
            "description": "The identifiers to erase. At least one is required, and a single request accepts at most 1000.",
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/DeletionIdentifier"
            }
          },
          "client_reference": {
            "description": "Optional caller-supplied reference echoed back on the job. Two identical requests submitted within 24 hours resolve to the same job.",
            "type": "string",
            "nullable": true,
            "example": "ticket-4821"
          }
        },
        "example": {
          "identifiers": [
            {
              "type": "email",
              "value": "end-user@example.com"
            },
            {
              "type": "end_user_id",
              "value": "6463dbcfafb2e65a02fbc5ee"
            },
            {
              "type": "variable_match",
              "value": "acme-corp",
              "variable": "company"
            }
          ],
          "client_reference": "ticket-4821"
        }
      },
      "DeletionJobStatus": {
        "description": "Lifecycle state of a deletion job. `queued` and `in_progress` are non-terminal; `completed`, `partial`, and `failed` are terminal.",
        "type": "string",
        "enum": [
          "queued",
          "in_progress",
          "completed",
          "partial",
          "failed"
        ],
        "example": "queued"
      },
      "DeletionRequestAccepted": {
        "type": "object",
        "description": "Acknowledgment returned when a deletion request is accepted for processing.",
        "properties": {
          "job_id": {
            "description": "Identifier of the created deletion job. Use it to poll job status.",
            "type": "string",
            "example": "job_01HXW...ZK"
          },
          "status": {
            "$ref": "#/components/schemas/DeletionJobStatus"
          },
          "submitted_count": {
            "description": "Number of identifiers received in the request.",
            "type": "integer",
            "example": 3
          },
          "created_at": {
            "description": "Time the job was created, in ISO 8601 format.",
            "type": "string",
            "format": "date-time",
            "example": "2026-07-10T14:05:00Z"
          }
        }
      },
      "IdentifierDisposition": {
        "type": "object",
        "description": "The outcome for one submitted identifier.",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/DeletionIdentifierType"
          },
          "value": {
            "description": "The identifier value as submitted.",
            "type": "string",
            "example": "end-user@example.com"
          },
          "variable": {
            "description": "The matched variable name, or null when not applicable.",
            "type": "string",
            "nullable": true,
            "example": null
          },
          "disposition": {
            "description": "How the identifier was handled. `accepted` identifiers are queued for erasure; the other values indicate the identifier contributed no erasure.",
            "type": "string",
            "enum": [
              "accepted",
              "not_found",
              "invalid",
              "exceeds_limit",
              "duplicate"
            ],
            "example": "accepted"
          },
          "matched_chatters": {
            "description": "Number of end users matched by this identifier.",
            "type": "integer",
            "minimum": 0,
            "maximum": 1000000,
            "example": 1
          },
          "reason": {
            "description": "Human-readable explanation for a non-accepted disposition. Always set for `invalid` and `exceeds_limit`, and for `not_found` on ID-based identifiers; may be null for a `not_found` `email` or `variable_match` selector, and for `accepted`/`duplicate`. Do not assume it is non-null from `disposition` alone.",
            "type": "string",
            "nullable": true,
            "example": null
          }
        }
      },
      "DeletionJob": {
        "type": "object",
        "description": "Full state of a deletion job, including the per-identifier outcomes.",
        "properties": {
          "job_id": {
            "description": "Identifier of the deletion job.",
            "type": "string",
            "example": "job_01HXW...ZK"
          },
          "type": {
            "description": "The job type.",
            "type": "string",
            "example": "end_user_deletion"
          },
          "client_reference": {
            "description": "The caller-supplied reference from the original request, or null.",
            "type": "string",
            "nullable": true,
            "example": "ticket-4821"
          },
          "status": {
            "$ref": "#/components/schemas/DeletionJobStatus"
          },
          "identifiers": {
            "description": "Per-identifier outcomes. Inspect this array to understand exactly what was erased, rather than relying on the top-level status alone.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IdentifierDisposition"
            }
          },
          "created_at": {
            "description": "Time the job was created, in ISO 8601 format.",
            "type": "string",
            "format": "date-time",
            "example": "2026-07-10T14:05:00Z"
          },
          "completed_at": {
            "description": "Time the job reached a terminal state, in ISO 8601 format, or null while the job is still running.",
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "failure_reason": {
            "description": "Opaque, machine-readable diagnostic present only when `status` is `failed`, or null otherwise. This value is subject to change; to understand outcomes per identifier, inspect each identifier's `disposition` and `reason`.",
            "type": "string",
            "nullable": true,
            "example": null
          }
        }
      }
    }
  },
  "paths": {
    "/v2/end-users/delete": {
      "post": {
        "summary": "Submit a bulk end-user deletion request",
        "description": "Submits a request to erase all personal data associated with the supplied identifiers. Replace `example` with your AI Agent's handle. A successful call returns a `202` with a `job_id` you can poll for status. Requests are idempotent for 24 hours: an identical resubmission within that window returns the original job instead of creating a new one.",
        "tags": [
          "Submit deletion request"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeletionRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The deletion request was accepted and a job was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionRequestAccepted"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body, for example no identifiers."
          },
          "401": {
            "description": "Authentication token is missing or invalid. Try generating a new token."
          },
          "403": {
            "description": "The token is not authorized to perform this operation."
          },
          "413": {
            "description": "The request body exceeds the maximum size of 512 KB. Split the identifiers across multiple requests."
          },
          "429": {
            "description": "Too many requests. Retry after slowing the request rate."
          },
          "500": {
            "description": "Something went wrong on Ada's end."
          }
        }
      }
    },
    "/v2/jobs/{job_id}": {
      "get": {
        "summary": "Get a deletion job",
        "description": "Returns the current state of a deletion job, including the per-identifier dispositions. A job for an unknown or unowned `job_id` returns `404`.",
        "tags": [
          "Get deletion job"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobId"
          }
        ],
        "responses": {
          "200": {
            "description": "The deletion job was found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionJob"
                }
              }
            }
          },
          "401": {
            "description": "Authentication token is missing or invalid. Try generating a new token."
          },
          "404": {
            "description": "No deletion job exists for the supplied `job_id` under this AI Agent."
          },
          "429": {
            "description": "Too many requests. Retry after slowing the request rate."
          },
          "500": {
            "description": "Something went wrong on Ada's end."
          }
        }
      }
    }
  }
}
