openapi: 3.1.0
info:
  title: "Contact Data API — Headless AI SDR (Reply.io)"
  version: "3.0"
  description: >
    The CRM-grade contact and account store — contacts, contact lists,
    custom fields, company accounts, and account lists.
    Summary specification for AI agents; the authoritative, complete reference is
    https://docs.reply.io/api-reference/contacts/list-all-contacts and the full
    platform OpenAPI at https://docs.reply.io/api-reference/bundled.yaml.
  contact:
    name: Reply.io
    url: "https://reply.io"
servers:
  - url: "https://api.reply.io/v3"
security:
  - bearerAuth: []
tags:
  - name: Contacts
  - name: Contact Lists
  - name: Custom Fields
  - name: Accounts
  - name: Account Lists
paths:
  /contacts:
    get:
      tags: [Contacts]
      operationId: listContacts
      summary: List all contacts
      description: Requires the `contacts:read` scope.
      responses:
        "200":
          description: Paginated list of contacts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Contact"
        "429":
          $ref: "#/components/responses/RateLimited"
    post:
      tags: [Contacts]
      operationId: createContact
      summary: Create a contact
      description: Requires the `contacts:write` scope.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                firstName:
                  type: string
                lastName:
                  type: string
                company:
                  type: string
                title:
                  type: string
      responses:
        "201":
          description: Contact created.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Contact"
        "403":
          $ref: "#/components/responses/Forbidden"
  /contacts/{contactId}:
    get:
      tags: [Contacts]
      operationId: getContact
      summary: Get a contact
      description: Requires the `contacts:read` scope.
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "200":
          description: The contact.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Contact"
    patch:
      tags: [Contacts]
      operationId: updateContact
      summary: Update a contact
      description: Requires the `contacts:write` scope.
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "200":
          description: Updated contact.
    delete:
      tags: [Contacts]
      operationId: deleteContact
      summary: Delete a contact
      description: Requires the `contacts:write` scope.
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "204":
          description: Deleted.
  /contacts/filter:
    post:
      tags: [Contacts]
      operationId: filterContacts
      summary: Filter contacts
      description: >
        Query contacts by field conditions to build segments.
        Requires the `contacts:read` scope.
      responses:
        "200":
          description: Contacts matching the filter.
  /contacts/import:
    post:
      tags: [Contacts]
      operationId: importContacts
      summary: Import contacts
      description: >
        Bulk-load a batch of contacts in a single request — preferred over
        per-contact create loops for large loads. Requires the `contacts:write` scope.
      responses:
        "202":
          description: Import accepted for processing.
        "429":
          $ref: "#/components/responses/RateLimited"
  /contact-lists:
    get:
      tags: [Contact Lists]
      operationId: listContactLists
      summary: List contact lists
      description: Requires the `contacts:read` scope.
      responses:
        "200":
          description: All contact lists.
    post:
      tags: [Contact Lists]
      operationId: createContactList
      summary: Create a contact list
      description: >
        Requires the `contacts:write` scope. Adding or moving contacts into a
        list requires the `contacts:operate` scope.
      responses:
        "201":
          description: Contact list created.
  /custom-fields:
    get:
      tags: [Custom Fields]
      operationId: listCustomFields
      summary: List all custom fields
      description: Requires the `contacts:read` scope.
      responses:
        "200":
          description: All custom field definitions.
    post:
      tags: [Custom Fields]
      operationId: createCustomField
      summary: Create a custom field
      description: Requires the `contacts:write` scope.
      responses:
        "201":
          description: Custom field created.
  /accounts:
    get:
      tags: [Accounts]
      operationId: listAccounts
      summary: List accounts
      description: Requires the `contacts:read` scope.
      responses:
        "200":
          description: Paginated list of company accounts.
    post:
      tags: [Accounts]
      operationId: createAccount
      summary: Create an account
      description: >
        Requires the `contacts:write` scope. Bulk create and bulk
        add/remove of contacts on an account are also available.
      responses:
        "201":
          description: Account created.
  /account-lists:
    get:
      tags: [Account Lists]
      operationId: listAccountLists
      summary: List account lists
      description: Requires the `contacts:read` scope.
      responses:
        "200":
          description: All account lists.
    post:
      tags: [Account Lists]
      operationId: createAccountList
      summary: Create an account list
      description: >
        Requires the `contacts:write` scope. Adding or moving accounts into a
        list requires the `contacts:operate` scope.
      responses:
        "201":
          description: Account list created.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Reply.io API key sent as a Bearer token. Create one in the Reply.io app under
        Settings → API Key. See https://docs.reply.io/api-reference/authentication.
  parameters:
    contactId:
      name: contactId
      in: path
      required: true
      schema:
        type: string
  schemas:
    Contact:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        company:
          type: string
        title:
          type: string
        createdAt:
          type: string
          format: date-time
    Problem:
      type: object
      description: RFC 7807 problem document (application/problem+json).
      properties:
        type: { type: string }
        title: { type: string }
        status: { type: integer }
        detail: { type: string }
  responses:
    Forbidden:
      description: The API key is missing a required scope.
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/Problem"
    RateLimited:
      description: >
        Rate limit exceeded (100 requests/minute, 3,000/hour per user). Honor the
        Retry-After header.
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/Problem"
