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

# Import List

> The one list import: phones, emails, or both from one CSV you host. The platform fetches `source_url` (HTTPS only, at most 50 MB, `text/csv`, `application/csv`, or `text/plain`), checks the columns you named against the file's headers and checks that the first rows of each named column hold phone numbers or email addresses, and returns `202` before writing a row. Nothing is written when a check fails.

**Columns.** Send `phone_column`, `email_column`, or both (they must differ). There is no automatic email-column detection: name the column. Without `merge_tags`, every column other than the chosen ones becomes a merge tag automatically. With `merge_tags`, phone numbers map only the columns you name, while emails map the named columns and also every remaining column by its default name. Custom field names for emails must match `^[a-z][a-z0-9_]{0,63}$`.

**Purpose.** `audience` (the default) makes ONE list. Both sides are polled on `GET /contact-lists/{id}`: `import` for the phone numbers and `email` for the emails (`email.status` is `processing` until `ready` or `failed`, with counts and `removed_at_upload`). An email-only audience is organization-wide even when you send `brand_id`. `consent` (where the addresses came from) is optional: it is allowed only for an audience with an `email_column`, and any other combination returns `400`. Omit it and no consent record is stored. Unknown top-level fields in the request body are ignored; unknown keys inside `merge_tags` and `consent` return `400`. Every refusal happens before anything is stored. `do_not_contact` adds the phone numbers to an opt-out list and records the emails as unsubscribes for the organization; the unsubscribes appear on `GET /email/suppressions` once the background job finishes (minutes for a large file). A do-not-contact import returns no `list_id`.

**Email access.** `email_column` requires email to be enabled for the organization; otherwise the request returns `403` `ENTITLEMENT_REQUIRED`.

**Replaces `POST /email/lists/import`**, which was removed. To migrate: send `name` as `list_name` (now required); the `mapping` entry whose value is `email` becomes `email_column`; other `mapping` entries become `merge_tags`; `consent`, `email_domain_id`, and `acquired` carry over unchanged.



## OpenAPI

````yaml /api-reference/openapi.json post /contact-lists/import
openapi: 3.1.0
info:
  title: Political Comms API
  summary: >-
    Direct-to-carrier political texting API for campaigns, PACs, advocacy
    organizations, fundraisers, and elected officials.
  description: >-
    Public REST API for the Political Comms platform. Surfaces include Projects
    (compose, test, schedule, send), Conversations (read inbound threads and
    reply inside them), Lists (one import for phone numbers and emails, and
    analysis), Media Files, Organizations and hierarchy, Brands, Campaigns,
    Tracking Domains, Phone Numbers, Analytics, and Billing.


    Authentication is an API key passed in the `X-API-Key` header. Keys are
    generated from the dashboard at Admin → API and are prefixed `pc_live_`. All
    POST and PATCH endpoints that mutate state are designed to be safe to retry,
    with optional `Idempotency-Key` headers for stronger guarantees. Rate limit
    is 600 requests per minute per key (bursts up to 600, refilling at 10 per
    second, the same for every scope; the `X-RateLimit-Limit` header reports
    your key's exact limit, and `Retry-After` on a 429 is the seconds until your
    next request is allowed).


    Webhooks emit `message.sent`, `message.delivered`, `message.failed`,
    `message.replied`, and `link.clicked` events. Payloads are HMAC-signed;
    validate the signature before trusting any payload.


    A Model Context Protocol (MCP) server is available at
    https://docs.politicalcomms.com/mcp for AI agents that need to search the
    documentation programmatically. The developer hub at
    https://politicalcomms.com/developers/ has quickstart examples in cURL, raw
    HTTP, and Python.
  version: 1.6.0
  termsOfService: https://politicalcomms.com/terms/
  contact:
    name: Political Comms Support
    email: support@politicalcomms.com
    url: https://docs.politicalcomms.com
  license:
    name: Proprietary
    url: https://politicalcomms.com/terms/
  x-logo:
    url: https://politicalcomms.com/images/brand/pcomms-logo-left-of-text.png
    altText: Political Comms
    backgroundColor: '#ffffff'
    href: https://politicalcomms.com/
  x-mcp:
    url: https://docs.politicalcomms.com/mcp
    discovery_url: https://docs.politicalcomms.com/.well-known/mcp
    transport: http
    auth: none
    tools:
      - search_political_comms
      - query_docs_filesystem_political_comms
      - submit_feedback
servers:
  - url: https://api.politicalcomms.com/v1
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Projects
    description: Create, edit, test, schedule, and inspect projects.
  - name: Conversations
    description: >-
      Read inbound threads and reply inside them from the same number.
      Conversations are created by project sends; the API never starts one.
  - name: Phone Numbers
    description: List phone numbers across 10DLC campaigns and toll-free verifications.
  - name: Toll-Free Verifications
    description: >-
      List toll-free verifications (carrier registrations) across your
      organization hierarchy.
  - name: Brands
    description: List brands across your organization hierarchy.
  - name: 10DLC Campaigns
    description: >-
      List 10DLC campaigns (carrier registrations) across your organization
      hierarchy.
  - name: Email Campaigns
    description: >-
      Create, schedule, and report on email campaigns. Pause, resume, and test
      sends are deliverability decisions a human makes while watching a send,
      and live in the dashboard.
  - name: Email Templates
    description: Create and read saved email templates.
  - name: Email Senders
    description: >-
      Read the sender identities (From addresses) on your verified domains.
      Identities carry the physical mailing address and paid-for-by disclaimer,
      so they are created and edited in the dashboard.
  - name: Email Suppressions
    description: >-
      Addresses that will not be emailed: unsubscribes, bounces, complaints, and
      addresses you add. Read, add, and lift them in bulk to keep your own
      opt-out record in sync with ours. They apply automatically to every email
      send.
  - name: Contact Lists
    description: >-
      List, import, and analyze lists. One import brings in phone numbers,
      emails, or both, or a do-not-contact file.
  - name: Media Files
    description: List, import, and fetch media files.
  - name: Sending Domains
    description: >-
      Read the sending domains in your organization and the DNS records to
      publish. Domains are added in the dashboard: DNS is published by hand, so
      creation is not part of the API.
  - name: Tracking Domains
    description: >-
      List active link-tracking domains. Use the returned ids as
      `link_tracking_domain_id` on project create/update.
  - name: Organizations
    description: List descendant organizations and hierarchy.
  - name: Billing
    description: Usage and billing data across your organization.
  - name: Analytics
    description: Message statistics and delivery performance.
paths:
  /contact-lists/import:
    post:
      tags:
        - Contact Lists
      summary: Import List
      description: >-
        The one list import: phones, emails, or both from one CSV you host. The
        platform fetches `source_url` (HTTPS only, at most 50 MB, `text/csv`,
        `application/csv`, or `text/plain`), checks the columns you named
        against the file's headers and checks that the first rows of each named
        column hold phone numbers or email addresses, and returns `202` before
        writing a row. Nothing is written when a check fails.


        **Columns.** Send `phone_column`, `email_column`, or both (they must
        differ). There is no automatic email-column detection: name the column.
        Without `merge_tags`, every column other than the chosen ones becomes a
        merge tag automatically. With `merge_tags`, phone numbers map only the
        columns you name, while emails map the named columns and also every
        remaining column by its default name. Custom field names for emails must
        match `^[a-z][a-z0-9_]{0,63}$`.


        **Purpose.** `audience` (the default) makes ONE list. Both sides are
        polled on `GET /contact-lists/{id}`: `import` for the phone numbers and
        `email` for the emails (`email.status` is `processing` until `ready` or
        `failed`, with counts and `removed_at_upload`). An email-only audience
        is organization-wide even when you send `brand_id`. `consent` (where the
        addresses came from) is optional: it is allowed only for an audience
        with an `email_column`, and any other combination returns `400`. Omit it
        and no consent record is stored. Unknown top-level fields in the request
        body are ignored; unknown keys inside `merge_tags` and `consent` return
        `400`. Every refusal happens before anything is stored. `do_not_contact`
        adds the phone numbers to an opt-out list and records the emails as
        unsubscribes for the organization; the unsubscribes appear on `GET
        /email/suppressions` once the background job finishes (minutes for a
        large file). A do-not-contact import returns no `list_id`.


        **Email access.** `email_column` requires email to be enabled for the
        organization; otherwise the request returns `403`
        `ENTITLEMENT_REQUIRED`.


        **Replaces `POST /email/lists/import`**, which was removed. To migrate:
        send `name` as `list_name` (now required); the `mapping` entry whose
        value is `email` becomes `email_column`; other `mapping` entries become
        `merge_tags`; `consent`, `email_domain_id`, and `acquired` carry over
        unchanged.
      operationId: importContactList
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - source_url
                - list_name
              properties:
                source_url:
                  type: string
                  format: uri
                  description: >-
                    HTTPS URL of the CSV, such as a presigned storage URL. At
                    most 50 MB; `text/csv`, `application/csv`, or `text/plain`.
                    Private and link-local addresses are refused, on every
                    redirect.
                organization_id:
                  type: string
                  description: >-
                    Target organization for the import. Defaults to the
                    organization that owns the API key. Send it to target a
                    sub-organization under an agency-tier parent; the API key is
                    always limited to its own organization tree (otherwise the
                    request returns 403 ORG_ACCESS_DENIED).
                  format: uuid
                brand_id:
                  type: string
                  description: >-
                    Optional. When provided, the list is scoped to this brand
                    and the brand's organization is used, so a brand in an
                    accessible sub-organization works without `organization_id`.
                    A brand that does not belong to an organization your API key
                    can access returns 404 BRAND_NOT_FOUND. If both are sent and
                    the brand belongs to a different accessible organization
                    than `organization_id`, the request returns 400
                    BRAND_ORG_MISMATCH. Ignored for the emails of an import: an
                    email list is organization-wide or scoped to one sending
                    domain (`email_domain_id`).
                  format: uuid
                list_name:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: >-
                    Name for the list. Names do not have to be unique. For
                    `do_not_contact`, the name of the opt-out list the phone
                    numbers go to.
                purpose:
                  type: string
                  enum:
                    - audience
                    - do_not_contact
                  default: audience
                  description: >-
                    `audience`: a list you send to. `do_not_contact`: phone
                    numbers become an opt-out list and emails become
                    unsubscribes, both applied automatically to every send.
                phone_column:
                  type: string
                  minLength: 1
                  description: >-
                    The CSV header holding the phone number. Send this,
                    `email_column`, or both. A header that is not in the file
                    returns `400` `PHONE_COLUMN_NOT_FOUND` with
                    `details.headers`.
                email_column:
                  type: string
                  minLength: 1
                  description: >-
                    The CSV header holding the email address. Must differ from
                    `phone_column`. A header that is not in the file returns
                    `400` `VALIDATION_ERROR` with `details: { field:
                    "email_column", headers }`. Requires email to be enabled for
                    the organization.
                merge_tags:
                  type: object
                  properties:
                    first_name:
                      type: string
                      minLength: 1
                    last_name:
                      type: string
                      minLength: 1
                    address:
                      type: string
                      minLength: 1
                    address_line_2:
                      type: string
                      minLength: 1
                    city:
                      type: string
                      minLength: 1
                    state:
                      type: string
                      minLength: 1
                    zip:
                      type: string
                      minLength: 1
                    custom_fields:
                      type: array
                      items:
                        type: object
                        properties:
                          csv_column:
                            type: string
                            minLength: 1
                          merge_tag:
                            type: string
                            minLength: 1
                        required:
                          - csv_column
                          - merge_tag
                        additionalProperties: true
                  description: >-
                    Maps CSV columns to contact merge fields. Unknown keys are
                    rejected with a 400. When omitted, or when it maps nothing,
                    every non-phone column gets a merge tag automatically: a
                    header that matches a standard field (first name, last name,
                    address, address line 2, city, state, zip, including common
                    aliases) gets the standard tag, and any other column gets a
                    tag named after its header in lowercase with underscores
                    (for example `Donor Tier` becomes `{donor_tier}`). When
                    supplied, the phone side maps only the columns named; the
                    email side maps the named columns and every remaining column
                    by its default name. With an `email_column`, custom field
                    names must match `^[a-z][a-z0-9_]{0,63}$` (lowercase,
                    starting with a letter, at most 64 characters).
                  additionalProperties: false
                consent:
                  type: object
                  description: >-
                    Optional. Where the email addresses came from. Allowed only
                    when `purpose` is `audience` and `email_column` is set; sent
                    with any other combination it returns `400`. Omit it and no
                    consent record is stored.
                  properties:
                    source:
                      type: string
                      enum:
                        - donation_form
                        - petition
                        - signup_form
                        - event
                        - purchased
                        - rented
                        - other
                      description: >-
                        How these people agreed to hear from you. Answer
                        honestly: `purchased` and `rented` change how the list
                        is treated, and an undeclared acquired list is the usual
                        cause of a mid-send deliverability pause.
                    note:
                      type: string
                      maxLength: 1000
                  required:
                    - source
                  additionalProperties: false
                email_domain_id:
                  type:
                    - string
                    - 'null'
                  format: uuid
                  description: >-
                    Scopes the emails to one sending domain. Omit or send null
                    for an organization-wide list any email campaign can use. An
                    unknown domain returns `404` `NOT_FOUND`.
                acquired:
                  type: boolean
                  description: >-
                    Optional, default `false`. `true` marks the email addresses
                    as purchased or rented. Acquired lists are not blocked from
                    sending, but they are sent more gradually, warming up on
                    half steps.
            examples:
              phoneOnly:
                summary: Phone numbers only
                value:
                  source_url: https://example.com/path/to/list.csv
                  brand_id: 7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64
                  list_name: Spring Outreach List
                  phone_column: phone
                  merge_tags:
                    first_name: first_name
                    last_name: last_name
                    address: street
                    address_line_2: street2
                    city: city
                    state: state
                    zip: zip
                    custom_fields:
                      - csv_column: donor_tier
                        merge_tag: tier
              phoneAndEmail:
                summary: Phone numbers and emails in one list
                value:
                  source_url: https://example.com/path/to/donors.csv
                  brand_id: 7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64
                  list_name: August donors
                  phone_column: phone
                  email_column: email
                  consent:
                    source: donation_form
                    note: Donate page opt-in checkbox
              emailOnly:
                summary: Emails only
                value:
                  source_url: https://example.com/path/to/signups.csv
                  list_name: Rally signups
                  email_column: Email Address
                  merge_tags:
                    first_name: First
                  consent:
                    source: signup_form
                  email_domain_id: null
              doNotContact:
                summary: Do not contact
                value:
                  source_url: https://example.com/path/to/do-not-contact.csv
                  list_name: Vendor do-not-contact file
                  purpose: do_not_contact
                  phone_column: phone
                  email_column: email
      responses:
        '202':
          description: >-
            Import accepted and running as background jobs. Poll `GET
            /contact-lists/{list_id}` for both: `import.status` for the phone
            numbers and `email.status` for the emails, each until `ready` or
            `failed`. A do-not-contact import has no `list_id`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      list_id:
                        type: string
                        format: uuid
                        description: The list. Absent for `do_not_contact`.
                      purpose:
                        type: string
                        enum:
                          - audience
                          - do_not_contact
                      name:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      total_rows:
                        type:
                          - integer
                          - 'null'
                      channels:
                        type: array
                        items:
                          type: string
                          enum:
                            - text
                            - email
                        description: >-
                          Which sides the import started: `text` for phone
                          numbers, `email` for emails.
                      imported_via_api:
                        type: boolean
                        description: Always true. Absent for `do_not_contact`.
                      email_import:
                        type: object
                        description: >-
                          Present on an audience with an `email_column`. Poll
                          the email side as `email.status` on `GET
                          /contact-lists/{list_id}`.
                        properties:
                          id:
                            type: string
                            format: uuid
                          status:
                            type: string
                            enum:
                              - queued
                        required:
                          - id
                          - status
                        additionalProperties: true
                    required:
                      - purpose
                      - name
                      - status
                      - total_rows
                      - channels
                    additionalProperties: true
                required:
                  - success
                  - data
                additionalProperties: true
              examples:
                phoneOnly:
                  summary: Phone numbers only
                  value:
                    success: true
                    data:
                      list_id: 3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42
                      purpose: audience
                      name: Spring Outreach List
                      status: processing
                      total_rows: 12500
                      channels:
                        - text
                      imported_via_api: true
                phoneAndEmail:
                  summary: Phone numbers and emails in one list
                  value:
                    success: true
                    data:
                      list_id: 3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42
                      purpose: audience
                      name: August donors
                      status: processing
                      total_rows: 4200
                      channels:
                        - text
                        - email
                      imported_via_api: true
                      email_import:
                        id: 0193f2a4-6c1e-7b5d-9a3f-2e8c4d6b1a70
                        status: queued
                emailOnly:
                  summary: Emails only
                  value:
                    success: true
                    data:
                      list_id: 3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42
                      purpose: audience
                      name: Rally signups
                      status: processing
                      total_rows: 980
                      channels:
                        - email
                      imported_via_api: true
                      email_import:
                        id: 0193f2a4-6c1e-7b5d-9a3f-2e8c4d6b1a70
                        status: queued
                doNotContact:
                  summary: Do not contact
                  value:
                    success: true
                    data:
                      purpose: do_not_contact
                      name: Vendor do-not-contact file
                      status: processing
                      total_rows: 310
                      channels:
                        - text
                        - email
        '400':
          description: >-
            The body failed validation (`VALIDATION_ERROR`, including an
            `email_column` that is not a header, with `details: { field:
            "email_column", headers }`, or a named column whose first rows are
            not what it was chosen for, such as `The column "SURVEY_LINK" does
            not contain email addresses. Choose the column that holds emails, or
            set the email column to None.` with `details: { field }`), the phone
            column is not a header (`PHONE_COLUMN_NOT_FOUND`, `details: {
            phoneColumn, headers }`), a merge tag is invalid
            (`INVALID_MERGE_TAGS`, `UNKNOWN_STANDARD_TAG`,
            `MERGE_TAG_COLUMN_NOT_FOUND`, `INVALID_MERGE_TAG_NAME`), the file is
            not a readable CSV (`INVALID_CSV`), the brand belongs to another
            organization than `organization_id` (`BRAND_ORG_MISMATCH`), or
            `source_url` is not a public HTTPS URL (`INVALID_SOURCE_URL`).
            Nothing is written.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: phone_column "Phone" not found in CSV headers
                code: PHONE_COLUMN_NOT_FOUND
                correlationId: 030bf857-922f-4b82-8fca-c5b0769c1590
                details:
                  phoneColumn: Phone
                  headers:
                    - first_name
                    - cell
                    - email
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            The API key lacks `public:write`, the organization is outside the
            key's hierarchy (`ORG_ACCESS_DENIED`), or `email_column` was sent
            and email is not enabled for the organization
            (`ENTITLEMENT_REQUIRED`).
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/AuthErrorResponse'
                  - $ref: '#/components/schemas/ErrorResponse'
              examples:
                orgAccessDenied:
                  summary: Resource outside the key's organization hierarchy
                  value:
                    error: >-
                      Access denied: You do not have permission to access this
                      organization's data
                    code: ORG_ACCESS_DENIED
                    correlationId: de038205-7c9c-4d4a-99bc-d7275a52f07e
                entitlementRequired:
                  summary: Organization is not entitled to this feature
                  value:
                    error: This feature requires enablement by Political Comms
                    code: ENTITLEMENT_REQUIRED
                    details:
                      entitlement: email
        '404':
          description: >-
            The brand does not exist or is outside the key's hierarchy
            (`BRAND_NOT_FOUND`), or the email domain was not found
            (`NOT_FOUND`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: 'Brand not found: 7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64'
                code: BRAND_NOT_FOUND
                correlationId: 030bf857-922f-4b82-8fca-c5b0769c1590
        '413':
          description: The file at `source_url` is larger than 50 MB (`FILE_TOO_LARGE`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: >-
                  source_url exceeded byte cap of 52428800 bytes during
                  streaming
                code: FILE_TOO_LARGE
        '415':
          description: >-
            The file at `source_url` is not served as `text/csv`,
            `application/csv`, or `text/plain` (`UNSUPPORTED_CONTENT_TYPE`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: >-
                  source_url Content-Type "application/octet-stream" is not
                  allowed
                code: UNSUPPORTED_CONTENT_TYPE
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          description: >-
            The file could not be fetched from `source_url`
            (`SOURCE_URL_FETCH_FAILED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: source_url returned HTTP 403
                code: SOURCE_URL_FETCH_FAILED
components:
  parameters:
    IdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        minLength: 16
        maxLength: 200
      description: >-
        Optional idempotency key: a unique string of 16-200 printable ASCII
        characters (a UUID is recommended). Retrying the write with the same key
        within 24 hours returns the stored response of the first call with an
        `X-Idempotent-Replayed: true` response header instead of executing it
        again. Reusing a key with a different request body returns `422`
        (`IDEMPOTENCY_MISMATCH`); a duplicate sent while the first call is still
        running returns `409` with a `Retry-After` header. Keys are scoped per
        endpoint and organization.
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message.
        code:
          type: string
          description: >-
            Machine-readable error code, e.g. VALIDATION_ERROR,
            ORG_ACCESS_DENIED, PROJECT_NOT_FOUND.
        correlationId:
          type: string
          description: Request correlation ID; include it in support requests.
        details:
          type:
            - array
            - object
          description: >-
            Present on some errors. For VALIDATION_ERROR, an array of { field,
            message, code } with one entry per rejected field (field is the
            dotted path); an object for other codes (e.g. insufficient-balance
            shortfall).
      required:
        - error
        - code
      additionalProperties: true
      description: >-
        Standard error body produced by the API error handler for 4xx/5xx
        responses.
    AuthErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Short error summary.
        message:
          type: string
          description: Human-readable detail.
      required:
        - error
        - message
      additionalProperties: true
      description: >-
        Error body returned by the API-key authentication layer (401 and
        permission 403s).
    RateLimitErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: string
        message:
          type: string
        code:
          type: string
          enum:
            - RATE_LIMIT_EXCEEDED
        statusCode:
          type: integer
          enum:
            - 429
        retryAfter:
          type: integer
          description: >-
            Seconds until the rate-limit window resets. Also sent as the
            Retry-After header.
      required:
        - success
        - error
        - code
        - statusCode
        - retryAfter
      additionalProperties: true
  responses:
    Unauthorized:
      description: Missing, malformed, revoked, or expired API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorResponse'
          example:
            error: API key required
            message: Please provide an API key in the X-API-Key header
    RateLimited:
      description: Rate limit exceeded. Check the Retry-After header.
      headers:
        Retry-After:
          description: Seconds until the window resets.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitErrorResponse'
          example:
            success: false
            error: Rate limit exceeded
            message: Maximum 600 requests per 60 seconds
            code: RATE_LIMIT_EXCEEDED
            statusCode: 429
            retryAfter: 3
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: An unexpected error occurred. Please try again later.
            code: INTERNAL_ERROR
            correlationId: de038205-7c9c-4d4a-99bc-d7275a52f07e
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Authenticate every request by passing your API key in the X-API-Key
        header. Keys are scoped to your organization hierarchy.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.