openapi: 3.0.3
info:
  title: TalkToHumans Public API
  version: 1.0.0
  license:
    name: Proprietary
  description: >
    Read and organize the LinkedIn organization data your team already manages
    in TalkToHumans: accounts, contacts, tags, notes, sequence state,
    conversations, and views.
servers:
  - url: https://api.talktohumans.app
    description: TalkToHumans API
security:
  - bearerAuth: []
tags:
  - name: Organization
    description: Organization details for the current API key.
  - name: LinkedIn
    description: LinkedIn accounts, contacts, companies, and conversations.
  - name: Activity
    description: Activity for organization reporting.
  - name: Enrich
    description: Profile enrichment for LinkedIn contacts and companies.
  - name: Views
    description: Saved TalkToHumans views.
paths:
  /v1/organization:
    get:
      tags:
        - Organization
      x-mint:
        href: /developers/accounts/get-organization
      operationId: getOrganization
      summary: Get organization
      description: Returns metadata about the current organization.
      responses:
        '200':
          description: Organization metadata.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetOrganizationResponse'
              example:
                organization:
                  - id: 123
                    name: Acme
                    created_at: '2026-05-10T12:00:00Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/accounts:
    get:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/accounts/list-accounts
      operationId: listAccounts
      summary: List connected accounts
      description: Lists connected LinkedIn accounts.
      responses:
        '200':
          description: Connected LinkedIn accounts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListAccountsEnvelope'
              example:
                data:
                  accounts:
                    - account_id: '42'
                      display_name: Jane Doe
                      provider_account_id: ACoAA000000
                      owner_user_id: '7'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/activity:
    get:
      tags:
        - Activity
      x-mint:
        href: /developers/activity/list-activity
      operationId: listActivity
      summary: List activity
      description: Lists activity events for the current organization.
      parameters:
        - $ref: '#/components/parameters/ActivityFrom'
        - $ref: '#/components/parameters/ActivityTo'
        - $ref: '#/components/parameters/ActivityTimezone'
        - $ref: '#/components/parameters/ActivityAccountId'
        - $ref: '#/components/parameters/ActivityUserId'
        - $ref: '#/components/parameters/ActivityEventType'
        - $ref: '#/components/parameters/ActivityChannel'
        - $ref: '#/components/parameters/ActivitySource'
        - $ref: '#/components/parameters/ActivityTag'
        - $ref: '#/components/parameters/ActivityLimit'
        - $ref: '#/components/parameters/ActivityCursor'
      responses:
        '200':
          description: Activity rows.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListActivityEnvelope'
              example:
                data:
                  generated_at: '2026-07-09T12:00:00Z'
                  timezone: America/Los_Angeles
                  filters:
                    from: '2026-07-01T07:00:00Z'
                    to: '2026-07-10T07:00:00Z'
                    to_exclusive: true
                    account_ids:
                      - '42'
                    event_types:
                      - message_sent
                      - outbound_reply_received
                    channels:
                      - linkedin_message
                    sources:
                      - canonical_messages
                    tag_attribution: unavailable
                  activity:
                    - id: '987'
                      occurred_at: '2026-07-09T10:30:00Z'
                      recorded_at: '2026-07-09T10:30:04Z'
                      event_type: message_sent
                      source: canonical_messages
                      channel: linkedin_message
                      user_id: '7'
                      account_id: '42'
                      subject_key: linkedin:participant:linkedin:urn:li:fsd_profile:abc
                      attribution_method: user_and_account
                      metadata:
                        provider_message_id: urn:li:msg:abc
                        provider_chat_id: urn:li:msg_conversation:def
                        message_source: linkedin_message
                  pagination:
                    limit: 50
                    has_more: false
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ReportingForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/activity/summary:
    get:
      tags:
        - Activity
      x-mint:
        href: /developers/activity/summarize-activity
      operationId: summarizeActivity
      summary: Summarize activity
      description: >-
        Summarizes LinkedIn activity and performance for the current
        organization.
      parameters:
        - $ref: '#/components/parameters/ActivityFrom'
        - $ref: '#/components/parameters/ActivityTo'
        - $ref: '#/components/parameters/ActivityTimezone'
        - $ref: '#/components/parameters/ActivityAccountId'
        - $ref: '#/components/parameters/ActivityUserId'
        - $ref: '#/components/parameters/ActivityEventType'
        - $ref: '#/components/parameters/ActivityChannel'
        - $ref: '#/components/parameters/ActivitySource'
        - $ref: '#/components/parameters/ActivityTag'
      responses:
        '200':
          description: Activity summary.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActivitySummaryEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ReportingForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/enrich:
    post:
      tags:
        - Enrich
      x-mint:
        href: /developers/enrich/enrich-profile
      operationId: enrichProfile
      summary: Enrich profile
      description: Enriches a LinkedIn profile and its primary company.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnrichProfileRequest'
            examples:
              linkedinUrl:
                summary: Enrich by LinkedIn URL
                value:
                  account_id: '42'
                  linkedin_url: https://www.linkedin.com/in/jane-doe/
              contactId:
                summary: Enrich an existing contact
                value:
                  account_id: '42'
                  contact_id: '123'
      responses:
        '200':
          description: LinkedIn profile and primary company enrichment data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnrichProfileEnvelope'
              example:
                data:
                  linkedin_enrichment:
                    profile:
                      participant:
                        provider: linkedin
                        provider_participant_id: urn:li:fsd_profile:abc
                        kind: member
                        public_identifier: jane-doe
                        profile_url: https://www.linkedin.com/in/jane-doe/
                        first_name: Jane
                        last_name: Doe
                        full_name: Jane Doe
                        headline: Founder at Acme
                        avatar_url: >-
                          https://media.licdn.com/dms/image/example/profile-displayphoto.jpg
                        background_cover_url: >-
                          https://media.licdn.com/dms/image/example/profile-cover.jpg
                        primary_company:
                          provider: linkedin
                          provider_participant_id: urn:li:fsd_company:123
                        primary_company_name: Acme
                        primary_role_title: Founder
                        profile_fetched_at: '2026-05-31T12:00:00Z'
                        updated_at: '2026-05-31T12:00:00Z'
                      languages:
                        - language: English
                          metadata_json: null
                      experiences:
                        - company:
                            provider: linkedin
                            provider_participant_id: urn:li:fsd_company:123
                          company_name: Acme
                          title: Founder
                          employment_type: Full-time
                          location: San Francisco Bay Area
                          start_at: 2021-01
                          end_at: null
                          is_current: true
                          description: Building business software for sales teams.
                          metadata_json: null
                      educations:
                        - school:
                            provider: linkedin
                            provider_participant_id: urn:li:fsd_company:987
                          school_name: Stanford University
                          degree: MBA
                          field_of_study: Business Administration
                          start_at: '2014'
                          end_at: '2016'
                          description: null
                          metadata_json: null
                      locations:
                        - source: linkedin
                          sort_order: 0
                          is_primary: true
                          is_headquarter: false
                          linkedin_text: San Francisco Bay Area
                          display_text: San Francisco, California, United States
                          country_code: US
                          region_code: US-CA
                          country: United States
                          country_full: United States
                          state: California
                          city: San Francisco
                          geographic_area: San Francisco Bay Area
                          line1: null
                          line2: null
                          postal_code: null
                          description: null
                          metadata_json: null
                      industries:
                        - sort_order: 0
                          industry_urn: urn:li:industry:4
                          provider_industry_id: '4'
                          name: Software Development
                          title: Software Development
                          hierarchy: Technology > Software
                          metadata_json: null
                    company:
                      participant:
                        provider: linkedin
                        provider_participant_id: urn:li:fsd_company:123
                        kind: company
                        public_identifier: acme
                        profile_url: https://www.linkedin.com/company/acme/
                        full_name: Acme
                        headline: Software Development
                        avatar_url: >-
                          https://media.licdn.com/dms/image/example/company-logo.jpg
                        background_cover_url: >-
                          https://media.licdn.com/dms/image/example/company-cover.jpg
                        headcount: 51-200
                        employee_count: 120
                        website_url: https://acme.example
                        follower_count: 12000
                        about: Acme builds business software.
                        profile_fetched_at: '2026-05-31T12:00:00Z'
                        updated_at: '2026-05-31T12:00:00Z'
                      languages:
                        - language: English
                          metadata_json: null
                      experiences:
                        - company: null
                          company_name: Acme
                          title: Company profile
                          employment_type: null
                          location: San Francisco, CA
                          start_at: null
                          end_at: null
                          is_current: true
                          description: null
                          metadata_json: null
                      educations:
                        - school: null
                          school_name: null
                          degree: null
                          field_of_study: null
                          start_at: null
                          end_at: null
                          description: null
                          metadata_json: null
                      locations:
                        - source: linkedin
                          sort_order: 0
                          is_primary: true
                          is_headquarter: true
                          linkedin_text: San Francisco, CA
                          display_text: San Francisco, California, United States
                          country_code: US
                          region_code: US-CA
                          country: United States
                          country_full: United States
                          state: California
                          city: San Francisco
                          geographic_area: San Francisco Bay Area
                          line1: null
                          line2: null
                          postal_code: null
                          description: null
                          metadata_json: null
                      industries:
                        - sort_order: 0
                          industry_urn: urn:li:industry:4
                          provider_industry_id: '4'
                          name: Software Development
                          title: Software Development
                          hierarchy: Technology > Software
                          metadata_json: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/BadGateway'
  /v1/contacts:
    post:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/contacts/import-contact
      operationId: importContact
      summary: Import contact
      description: |
        Imports a contact
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImportContactRequest'
            example:
              account_id: '42'
              linkedin_url: https://www.linkedin.com/in/jane-doe/
      responses:
        '200':
          description: Contact was already attached to the LinkedIn account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportContactEnvelope'
              example:
                data:
                  contact:
                    account_relationship_id: '1042'
                    contact_id: '123'
                    provider_participant_id: urn:li:fsd_profile:abc
                    public_identifier: jane-doe
                    account:
                      account_id: '42'
                      display_name: Jane Doe
                      provider_account_id: ACoAA000000
                      owner_user_id: '7'
                    name: Jane Doe
                    first_name: Jane
                    last_name: Doe
                    headline: Founder at Acme
                    primary_role_title: Founder
                    primary_company_name: Acme
                    linkedin_url: https://www.linkedin.com/in/jane-doe/
                    relationship_status: unknown
                    tags: []
                    languages: []
                    experiences: []
                    educations: []
                    locations: []
                    app_url: https://app.talktohumans.app/contacts
                  warnings: []
        '201':
          description: >-
            Contact imported and attached to the LinkedIn account for the first
            time.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportContactEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/BadGateway'
    get:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/contacts/list-contacts
      operationId: listContacts
      summary: List contacts
      description: Lists LinkedIn contacts.
      parameters:
        - $ref: '#/components/parameters/AccountId'
        - name: query
          in: query
          description: >-
            Search by name, headline, company, role, LinkedIn handle, or profile
            URL.
          schema:
            type: string
        - name: company_name
          in: query
          description: Filter by current or past company name.
          schema:
            type: string
        - name: headline
          in: query
          description: Filter by headline text.
          schema:
            type: string
        - name: search
          in: query
          description: >-
            Search broadly across profile details, tags, notes, locations, work
            history, education, and company data.
          schema:
            type: string
        - name: location
          in: query
          description: Filter by location text.
          schema:
            type: string
        - name: company_size
          in: query
          description: Filter by company size or employee count.
          schema:
            type: string
        - name: tag
          in: query
          description: Filter by tag name.
          schema:
            type: string
        - name: relationship_status
          in: query
          description: Filter by LinkedIn relationship state. Defaults to `any`.
          schema:
            type: string
            enum:
              - any
              - connected
              - not_connected
              - unknown
        - name: invitation_status
          in: query
          description: Filter by invitation state. Only `pending` is currently supported.
          schema:
            type: string
            enum:
              - pending
        - name: conversation_id
          in: query
          description: >-
            Return contacts who participate in the given TalkToHumans
            conversation.
          schema:
            type: string
        - name: view_id
          in: query
          description: >
            Return only contacts that belong to a saved TalkToHumans view
            (list).

            Accepts the view `id` or `public_id` returned by `GET /v1/views`.

            Works for views created in the app and views created with `POST
            /v1/views`.

            Results are scoped to the view's LinkedIn account.
          schema:
            type: string
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Contacts matching the filters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListContactsEnvelope'
              example:
                data:
                  contacts:
                    - account_relationship_id: '1042'
                      contact_id: '123'
                      provider_participant_id: urn:li:fsd_profile:abc
                      public_identifier: jane-doe
                      account:
                        account_id: '42'
                        display_name: Jane Doe
                        provider_account_id: ACoAA000000
                        owner_user_id: '7'
                      name: Jane Doe
                      first_name: Jane
                      last_name: Doe
                      headline: Founder at Acme
                      primary_role_title: Founder
                      primary_company_name: Acme
                      work_email: jane@acme.example
                      phone: '+14155550123'
                      linkedin_url: https://www.linkedin.com/in/jane-doe/
                      avatar_url: >-
                        https://media.licdn.com/dms/image/example/profile-displayphoto.jpg
                      background_cover_url: >-
                        https://media.licdn.com/dms/image/example/profile-cover.jpg
                      relationship_status: connected
                      Deal stage: Qualified
                      Lead score: 91
                      Next follow-up: '2026-07-01'
                      VIP: true
                      tags:
                        - name: Hot lead
                          color: red
                      languages:
                        - language: English
                      experiences:
                        - experience_id: exp_2f8c1b
                          company_participant_id: linkedin:participant:urn:li:fsd_company:123
                          company_provider_participant_id: urn:li:fsd_company:123
                          company_name: Acme
                          title: Founder
                          employment_type: Full-time
                          location: San Francisco Bay Area
                          start_at: 2021-01
                          is_current: true
                          description: Building business software for sales teams.
                      educations:
                        - education_id: edu_91ac42
                          school_participant_id: linkedin:participant:urn:li:fsd_company:987
                          school_provider_participant_id: urn:li:fsd_company:987
                          school_name: Stanford University
                          degree: MBA
                          field_of_study: Business Administration
                          start_at: '2014'
                          end_at: '2016'
                      locations:
                        - linkedin_text: San Francisco Bay Area
                          display_text: San Francisco, California, United States
                          country_code: US
                          region_code: US-CA
                          country: United States
                          country_full: United States
                          state: California
                          city: San Francisco
                          geographic_area: San Francisco Bay Area
                          is_primary: true
                          is_headquarter: false
                      company:
                        company_id: linkedin:participant:urn:li:fsd_company:123
                        provider_participant_id: urn:li:fsd_company:123
                        public_identifier: acme
                        name: Acme
                        linkedin_url: https://www.linkedin.com/company/acme/
                        avatar_url: >-
                          https://media.licdn.com/dms/image/example/company-logo.jpg
                        background_cover_url: >-
                          https://media.licdn.com/dms/image/example/company-cover.jpg
                        headline: Software Development
                        headcount: 51-200
                        employee_count: 120
                        website_url: https://acme.example
                        follower_count: 12000
                        about: Acme builds business software.
                        industries:
                          - name: Software Development
                            title: Software Development
                            industry_urn: urn:li:industry:4
                            provider_industry_id: '4'
                            hierarchy: Technology > Software
                        locations:
                          - linkedin_text: San Francisco, CA
                            display_text: San Francisco, California, United States
                            country_code: US
                            region_code: US-CA
                            country: United States
                            country_full: United States
                            state: California
                            city: San Francisco
                            geographic_area: San Francisco Bay Area
                            is_primary: true
                            is_headquarter: true
                      app_url: https://app.talktohumans.app/contacts
                  pagination:
                    limit: 10
                    has_more: false
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/contacts/{contact_id}:
    patch:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/contacts/update-contact
      operationId: updateContact
      summary: Update contact
      description: Updates a LinkedIn contact.
      parameters:
        - name: contact_id
          in: path
          required: true
          description: Contact ID returned by `GET /v1/contacts`.
          schema:
            type: string
            pattern: ^[1-9][0-9]*$
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateContactRequest'
            examples:
              addRemoveTags:
                summary: Add and remove tags
                value:
                  account_id: '42'
                  tags:
                    add:
                      - name: Hot lead
                        color: red
                    remove:
                      - Old tag
              setTags:
                summary: Replace tags
                value:
                  account_id: '42'
                  tags:
                    set:
                      - name: Customer
                        color: green
              clearNotes:
                summary: Clear notes
                value:
                  account_id: '42'
                  notes_json: null
              setCustomFields:
                summary: Set custom fields
                description: Each custom field key is the field's registered name.
                value:
                  account_id: '42'
                  Deal stage: Qualified
                  Lead score: 91
                  Next follow-up: '2026-07-01'
                  VIP: true
              clearCustomField:
                summary: Clear a custom field
                value:
                  account_id: '42'
                  Next follow-up: null
      responses:
        '200':
          description: Contact updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateContactEnvelope'
              example:
                data:
                  contact:
                    account_relationship_id: '1042'
                    contact_id: '123'
                    provider_participant_id: urn:li:fsd_profile:abc
                    public_identifier: jane-doe
                    account:
                      account_id: '42'
                      display_name: Jane Doe
                      provider_account_id: ACoAA000000
                      owner_user_id: '7'
                    name: Jane Doe
                    first_name: Jane
                    last_name: Doe
                    headline: Founder at Acme
                    primary_role_title: Founder
                    primary_company_name: Acme
                    work_email: jane@acme.example
                    phone: '+14155550123'
                    linkedin_url: https://www.linkedin.com/in/jane-doe/
                    avatar_url: >-
                      https://media.licdn.com/dms/image/example/profile-displayphoto.jpg
                    background_cover_url: >-
                      https://media.licdn.com/dms/image/example/profile-cover.jpg
                    relationship_status: connected
                    Deal stage: Qualified
                    Lead score: 91
                    Next follow-up: '2026-07-01'
                    VIP: true
                    tags:
                      - name: Hot lead
                        color: red
                    notes_json: '[{"id":"n1","content":"Follow up next week"}]'
                    languages:
                      - language: English
                    experiences:
                      - experience_id: exp_2f8c1b
                        company_participant_id: linkedin:participant:urn:li:fsd_company:123
                        company_provider_participant_id: urn:li:fsd_company:123
                        company_name: Acme
                        title: Founder
                        employment_type: Full-time
                        location: San Francisco Bay Area
                        start_at: 2021-01
                        is_current: true
                        description: Building business software for sales teams.
                    educations:
                      - education_id: edu_91ac42
                        school_participant_id: linkedin:participant:urn:li:fsd_company:987
                        school_provider_participant_id: urn:li:fsd_company:987
                        school_name: Stanford University
                        degree: MBA
                        field_of_study: Business Administration
                        start_at: '2014'
                        end_at: '2016'
                    locations:
                      - linkedin_text: San Francisco Bay Area
                        display_text: San Francisco, California, United States
                        country_code: US
                        region_code: US-CA
                        country: United States
                        country_full: United States
                        state: California
                        city: San Francisco
                        geographic_area: San Francisco Bay Area
                        is_primary: true
                        is_headquarter: false
                    app_url: https://app.talktohumans.app/contacts
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/companies:
    get:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/companies/list-companies
      operationId: listCompanies
      summary: List companies
      description: Lists LinkedIn companies.
      parameters:
        - $ref: '#/components/parameters/AccountId'
        - name: view_id
          in: query
          description: >
            Optional. Return only companies associated with contacts in a saved
            TalkToHumans contact view.

            Accepts the view `id` or `public_id` returned by `GET /v1/views`.

            When provided, results are scoped to the view's LinkedIn account and
            `account_id` is ignored.
          schema:
            type: string
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Companies matching the filters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListCompaniesEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/companies/{company_id}:
    patch:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/companies/update-company
      operationId: updateCompany
      summary: Update company
      description: Updates a LinkedIn company.
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company ID returned by `GET /v1/companies` (the `company_id` field).
          schema:
            type: string
            pattern: ^[1-9][0-9]*$
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCompanyRequest'
            examples:
              setCustomFields:
                summary: Set custom fields
                description: Each custom field key is the field's registered name.
                value:
                  account_id: '42'
                  Deal stage: Negotiation
                  ARR: 50000
              setTags:
                summary: Replace tags
                value:
                  account_id: '42'
                  tags:
                    set:
                      - name: Target account
                        color: green
              clearNotes:
                summary: Clear notes
                value:
                  account_id: '42'
                  notes_json: null
      responses:
        '200':
          description: Company updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateCompanyEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/conversations:
    get:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/conversations/list-conversations
      operationId: listConversations
      summary: List conversations
      description: Lists LinkedIn conversations.
      parameters:
        - name: tag
          in: query
          description: >-
            Filter by a participant tag. The connected account's own profile is
            ignored.
          schema:
            type: string
        - name: contact_id
          in: query
          description: >-
            Filter by TalkToHumans contact ID. Use a positive integer encoded as
            a string.
          schema:
            type: string
            pattern: ^[1-9][0-9]*$
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Conversations matching the filters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListConversationsEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/conversations/{conversationId}/messages:
    get:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/conversations/list-conversation-messages
      operationId: listConversationMessages
      summary: List conversation messages
      description: Lists messages from a LinkedIn conversation.
      parameters:
        - name: conversationId
          in: path
          required: true
          description: Conversation ID returned by `GET /v1/conversations`.
          schema:
            type: string
        - name: account_id
          in: query
          required: true
          description: LinkedIn account ID returned by `GET /v1/accounts`.
          schema:
            type: string
            pattern: ^[1-9][0-9]*$
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Messages in the conversation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListConversationMessagesEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/drafts:
    post:
      tags:
        - LinkedIn
      x-mint:
        href: /developers/conversations/create-message-draft
      operationId: createMessageDraft
      summary: Create message draft
      description: |
        Create or replace a message or connection request draft
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMessageDraftRequest'
            examples:
              contact:
                summary: Draft a new message to an imported contact
                value:
                  account_id: '42'
                  contact_id: '123'
                  draft_message: Hi Jane, it was great learning about Acme.
              conversation:
                summary: Draft a reply to an existing conversation
                value:
                  account_id: '42'
                  conversation_id: chat_abc123
                  draft_message: Thanks for the thoughtful note. Would Tuesday work?
      responses:
        '200':
          description: Draft saved in TalkToHumans. The message was not sent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateMessageDraftEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v1/views:
    get:
      tags:
        - Views
      x-mint:
        href: /developers/views/list-views
      operationId: listViews
      summary: List contact views
      description: Lists saved TalkToHumans contact views.
      parameters:
        - $ref: '#/components/parameters/AccountId'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Saved contact views.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListViewsEnvelope'
              example:
                data:
                  views:
                    - id: '789'
                      public_id: mem_2f5e3a4b
                      type: contact
                      view_kind: member
                      name: Relevant leads
                      description: Leads found in my network
                      account:
                        account_id: '42'
                        display_name: Jane Doe
                        provider_account_id: ACoAA000000
                        owner_user_id: '7'
                      app_url: https://app.talktohumans.app/contacts/mem_2f5e3a4b
                      created_at: '2026-05-12T12:00:00Z'
                      updated_at: '2026-05-12T12:00:00Z'
                  pagination:
                    limit: 10
                    has_more: false
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      tags:
        - Views
      x-mint:
        href: /developers/views/create-view
      operationId: createView
      summary: Create contact view
      description: Creates a TalkToHumans contact view from specific contacts.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateViewRequest'
            example:
              account_id: '42'
              type: contact
              name: Relevant leads
              description: Leads found in my network
              filters:
                specific_contacts:
                  contact_ids:
                    - '123'
                    - '456'
      responses:
        '201':
          description: Contact view created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateViewEnvelope'
              example:
                data:
                  view:
                    id: '789'
                    public_id: mem_2f5e3a4b
                    type: contact
                    view_kind: member
                    name: Relevant leads
                    description: Leads found in my network
                    account:
                      account_id: '42'
                      display_name: Jane Doe
                      provider_account_id: ACoAA000000
                      owner_user_id: '7'
                    selected_contact_ids:
                      - '123'
                      - '456'
                    simple_filters_json: >-
                      {"combinator":"and","not":false,"rules":[{"field":"specific_contacts","operator":"contains","value":["linkedin:participant:urn:li:fsd_profile:abc"],"id":"8f20a6c8-9f18-4db6-931f-a018f815c604","valueSource":"value"}]}
                    app_url: https://app.talktohumans.app/contacts/mem_2f5e3a4b
                    created_at: '2026-05-12T12:00:00Z'
                    updated_at: '2026-05-12T12:00:00Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountScopedForbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Pass API key as `Authorization: Bearer <api_key>`.'
  parameters:
    AccountId:
      name: account_id
      in: query
      description: >
        LinkedIn account IDs returned by `GET /v1/accounts`.


        Repeat the query parameter for multiple accounts. The backend also
        accepts comma-separated values.

        If an explicit account target is not accessible to this credential, the
        API returns `403 account_shared_access_required`.
      schema:
        type: array
        items:
          type: string
          pattern: ^[1-9][0-9]*$
      style: form
      explode: true
    Limit:
      name: limit
      in: query
      description: Page size. Defaults to 10. Values above 25 are clamped to 25.
      schema:
        type: integer
        minimum: 1
        default: 10
        maximum: 25
    Cursor:
      name: cursor
      in: query
      description: Opaque cursor from the previous response's `pagination.next_cursor`.
      schema:
        type: string
    ActivityFrom:
      name: from
      in: query
      description: |
        Inclusive activity window start. Use RFC3339 or `YYYY-MM-DD`.
        Date-only values are interpreted in the requested `timezone`.
      schema:
        type: string
      example: '2026-07-01'
    ActivityTo:
      name: to
      in: query
      description: >
        Exclusive activity window end. Use RFC3339 or `YYYY-MM-DD`.

        Date-only values are interpreted in the requested `timezone` and advance
        to the start of the following local day.

        The response repeats the normalized instant in `filters.to` with
        `to_exclusive: true`.
      schema:
        type: string
      example: '2026-07-10'
    ActivityTimezone:
      name: timezone
      in: query
      description: >-
        IANA timezone used for date-only `from` and `to` filters. Defaults to
        `UTC`.
      schema:
        type: string
        default: UTC
      example: America/Los_Angeles
    ActivityAccountId:
      name: account_id
      in: query
      description: >
        Filter by TalkToHumans LinkedIn account ID in activity facts.

        Repeat the query parameter for multiple accounts. The backend also
        accepts comma-separated values.
      schema:
        type: array
        items:
          type: string
          pattern: ^[1-9][0-9]*$
      style: form
      explode: true
    ActivityUserId:
      name: user_id
      in: query
      description: >
        Filter by TalkToHumans user ID in activity facts.

        Repeat the query parameter for multiple users. The backend also accepts
        comma-separated values.
      schema:
        type: array
        items:
          type: string
          pattern: ^[1-9][0-9]*$
      style: form
      explode: true
    ActivityEventType:
      name: event_type
      in: query
      description: >
        Filter by activity event type.

        Repeat the query parameter for multiple event types. The backend also
        accepts comma-separated values.
      schema:
        type: array
        items:
          $ref: '#/components/schemas/ActivityEventType'
      style: form
      explode: true
    ActivityChannel:
      name: channel
      in: query
      description: >
        Filter by activity channel, such as `linkedin_message`,
        `linkedin_inmail`, or `linkedin_connection`.

        Repeat the query parameter for multiple channels. The backend also
        accepts comma-separated values.
      schema:
        type: array
        items:
          type: string
      style: form
      explode: true
    ActivitySource:
      name: source
      in: query
      description: >
        Filter by activity emitter source, such as `canonical_messages`,
        `canonical_chats`,

        `canonical_sequence_steps`, `sequence_runner_report`, or
        `canonical_account_participants`.

        Repeat the query parameter for multiple sources. The backend also
        accepts comma-separated values.
      schema:
        type: array
        items:
          type: string
      style: form
      explode: true
    ActivityTag:
      name: tag
      in: query
      description: >-
        Reserved for future tag-attributed reporting. Passing this parameter
        currently returns `400 bad_request`.
      schema:
        type: string
    ActivityLimit:
      name: limit
      in: query
      description: >-
        Page size for `GET /v1/activity`. Defaults to 50 and must be between 1
        and 200.
      schema:
        type: integer
        minimum: 1
        maximum: 200
        default: 50
    ActivityCursor:
      name: cursor
      in: query
      description: >-
        Opaque cursor from the previous `GET /v1/activity` response's
        `pagination.next_cursor`.
      schema:
        type: string
  responses:
    BadRequest:
      description: Invalid request parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: bad_request
            message: Invalid request parameters
    Unauthorized:
      description: Missing, malformed, invalid, or retired local API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missingAuthorization:
              value:
                code: unauthorized
                message: Authorization header is required
            invalidAuthorizationFormat:
              value:
                code: unauthorized
                message: Authorization header must use Bearer scheme
            invalidAPIKey:
              value:
                code: unauthorized
                message: Invalid API key
    Forbidden:
      description: >-
        API access is not enabled for the organization, or the API key cannot
        resolve to an active organization user.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            forbidden:
              value:
                code: forbidden
                message: you don't have access to this organization
            featureUnavailable:
              value:
                code: billing_feature_not_available
                message: >-
                  Feature 'TalkToHumansAPI' is not available in your current
                  plan
            insufficientCredits:
              value:
                code: billing_insufficient_credits
                message: Insufficient credits
            apiKeyPrincipalInvalid:
              value:
                code: forbidden
                message: >-
                  This API key is no longer linked to an active organization
                  user. Ask an organization admin to regenerate it
    AccountScopedForbidden:
      description: >-
        API access is not enabled for the organization, the API key cannot
        resolve to an active organization user, or the credential cannot access
        the requested LinkedIn account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            accountSharedAccessRequired:
              summary: Requested account is not accessible to this credential
              value:
                code: account_shared_access_required
                message: >-
                  This account is not shared-access enabled for API or MCP. Ask
                  an admin to enable shared access before using this account
                  from this credential.
            forbidden:
              value:
                code: forbidden
                message: you don't have access to this organization
            featureUnavailable:
              value:
                code: billing_feature_not_available
                message: >-
                  Feature 'TalkToHumansAPI' is not available in your current
                  plan
            insufficientCredits:
              value:
                code: billing_insufficient_credits
                message: Insufficient credits
            apiKeyPrincipalInvalid:
              value:
                code: forbidden
                message: >-
                  This API key is no longer linked to an active organization
                  user. Ask an organization admin to regenerate it
    ReportingForbidden:
      description: >-
        API access is not enabled for the organization, the API key cannot
        resolve to an active organization user, or the credential's user is not
        an organization admin.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            adminRequired:
              summary: Reporting requires an admin API-key principal
              value:
                code: forbidden
                message: Only organization admins can perform this action.
            forbidden:
              value:
                code: forbidden
                message: you don't have access to this organization
            featureUnavailable:
              value:
                code: billing_feature_not_available
                message: >-
                  Feature 'TalkToHumansAPI' is not available in your current
                  plan
            insufficientCredits:
              value:
                code: billing_insufficient_credits
                message: Insufficient credits
            apiKeyPrincipalInvalid:
              value:
                code: forbidden
                message: >-
                  This API key is no longer linked to an active organization
                  user. Ask an organization admin to regenerate it
    NotFound:
      description: Requested resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: not_found
            message: participant not found
    Conflict:
      description: Request conflicts with an existing resource.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: conflict
            message: custom field key already exists
    RateLimited:
      description: >-
        Rate limit exceeded. Public routes allow 50 requests per 10 seconds per
        IP and endpoint.
      headers:
        Retry-After:
          description: Seconds to wait before retrying the request.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: rate_limit_exceeded
            message: Rate limit exceeded
    BadGateway:
      description: Upstream provider request failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: upstream_error
            message: Enrichment provider request failed
    InternalServerError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: internal_error
            message: An internal error occurred
  schemas:
    Error:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable error code.
          enum:
            - unauthorized
            - forbidden
            - not_found
            - bad_request
            - internal_error
            - conflict
            - rate_limit_exceeded
            - account_shared_access_required
            - billing_payment_failed
            - billing_subscription_incomplete
            - billing_subscription_expired
            - billing_grace_period
            - billing_feature_not_available
            - billing_insufficient_credits
            - billing_invalid
            - upstream_error
        message:
          type: string
          description: Human-readable error message.
        debug:
          type: string
          description: Development-only debug details.
    GetOrganizationResponse:
      type: object
      additionalProperties: false
      required:
        - organization
      properties:
        organization:
          type: array
          items:
            $ref: '#/components/schemas/Organization'
    Organization:
      type: object
      additionalProperties: false
      properties:
        id:
          type: integer
          format: int32
        name:
          type: string
        created_at:
          type: string
          format: date-time
    ListAccountsEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ListAccountsResponse'
    ListAccountsResponse:
      type: object
      additionalProperties: false
      required:
        - accounts
      properties:
        accounts:
          type: array
          items:
            $ref: '#/components/schemas/AccountSummary'
    ListActivityEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ActivityListResponse'
    ActivityListResponse:
      type: object
      additionalProperties: false
      required:
        - generated_at
        - timezone
        - filters
        - activity
        - pagination
      properties:
        generated_at:
          type: string
          format: date-time
        timezone:
          type: string
          description: IANA timezone used to interpret date-only request filters.
        filters:
          $ref: '#/components/schemas/ActivityFilters'
        activity:
          type: array
          items:
            $ref: '#/components/schemas/ActivityEvent'
        pagination:
          $ref: '#/components/schemas/ActivityPagination'
    ActivitySummaryEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ActivitySummaryResponse'
    ActivitySummaryResponse:
      type: object
      additionalProperties: false
      required:
        - generated_at
        - timezone
        - totals
        - by_event_type
        - by_channel
        - by_source
        - by_user
        - by_account
        - by_template
        - template_metrics_basis
        - metrics
      properties:
        generated_at:
          type: string
          format: date-time
        timezone:
          type: string
        totals:
          $ref: '#/components/schemas/ActivitySummaryTotals'
        by_event_type:
          type: array
          items:
            $ref: '#/components/schemas/ActivityStringCount'
        by_channel:
          type: array
          items:
            $ref: '#/components/schemas/ActivityStringCount'
        by_source:
          type: array
          items:
            $ref: '#/components/schemas/ActivityStringCount'
        by_user:
          type: array
          items:
            $ref: '#/components/schemas/ActivityIdCount'
        by_account:
          type: array
          items:
            $ref: '#/components/schemas/ActivityIdCount'
        by_template:
          type: array
          description: >-
            Per-template conversion metrics derived from attributed activity
            facts.
          items:
            $ref: '#/components/schemas/ActivityTemplateMetrics'
        template_metrics_basis:
          type: string
          description: >-
            Run activation and single-reply attribution rule used for
            per-template rates.
        metrics:
          $ref: '#/components/schemas/ActivityDerivedMetrics'
    ActivitySummaryTotals:
      type: object
      additionalProperties: false
      required:
        - events
        - unattributed_user_events
        - unattributed_account_events
      properties:
        events:
          type: integer
        unattributed_user_events:
          type: integer
        unattributed_account_events:
          type: integer
    ActivityStringCount:
      type: object
      additionalProperties: false
      required:
        - count
      properties:
        key:
          type: string
        count:
          type: integer
        missing:
          type: boolean
    ActivityIdCount:
      type: object
      additionalProperties: false
      required:
        - count
      properties:
        id:
          type: string
        count:
          type: integer
        unattributed:
          type: boolean
    ActivityDerivedMetrics:
      type: object
      additionalProperties: false
      required:
        - contacts_contacted_outbound
        - contacts_replied_to_outbound
        - reply_rate
        - connection_requests_sent
        - connection_requests_accepted
        - connection_request_acceptance_rate
        - basis
      properties:
        contacts_contacted_outbound:
          type: integer
        contacts_replied_to_outbound:
          type: integer
        reply_rate:
          type: number
          format: double
          minimum: 0
          maximum: 1
          nullable: true
        connection_requests_sent:
          type: integer
        connection_requests_accepted:
          type: integer
        connection_request_acceptance_rate:
          type: number
          format: double
          minimum: 0
          maximum: 1
          nullable: true
        basis:
          type: string
          description: >-
            Explicit distinct-subject and numerator-intersection rule used for
            the rates.
    ActivityTemplateMetrics:
      type: object
      additionalProperties: false
      required:
        - template_key
        - template_public_id
        - template_type
        - outreach_runs_started
        - outreach_runs_replied
        - reply_rate
        - connection_requests_sent
        - connection_requests_accepted
        - connection_request_acceptance_rate
      properties:
        template_key:
          type: string
          description: Stable opaque template identity including scope and ownership.
        template_public_id:
          type: string
        template_type:
          type: string
          enum:
            - normal
            - sequence
        outreach_runs_started:
          type: integer
          description: Distinct template runs activated after a delivered outbound action.
        outreach_runs_replied:
          type: integer
          description: Activated template runs credited with a reply.
        reply_rate:
          type: number
          format: double
          minimum: 0
          maximum: 1
          nullable: true
        connection_requests_sent:
          type: integer
        connection_requests_accepted:
          type: integer
        connection_request_acceptance_rate:
          type: number
          format: double
          minimum: 0
          maximum: 1
          nullable: true
    ActivityFilters:
      type: object
      additionalProperties: false
      required:
        - to_exclusive
        - tag_attribution
      properties:
        from:
          type: string
          format: date-time
          description: Normalized inclusive lower bound in UTC, when supplied.
        to:
          type: string
          format: date-time
          description: Normalized exclusive upper bound in UTC, when supplied.
        to_exclusive:
          type: boolean
          description: >-
            Always true. Activity queries include events where `occurred_at <
            to`.
        account_ids:
          type: array
          items:
            type: string
        user_ids:
          type: array
          items:
            type: string
        event_types:
          type: array
          items:
            $ref: '#/components/schemas/ActivityEventType'
        channels:
          type: array
          items:
            type: string
        sources:
          type: array
          items:
            type: string
        tag_attribution:
          type: string
          enum:
            - unavailable
          description: >-
            Tag filtering is intentionally unavailable until activity events
            include tag attribution metadata.
    ActivityEvent:
      type: object
      additionalProperties: false
      required:
        - id
        - occurred_at
        - recorded_at
        - event_type
        - source
        - attribution_method
      properties:
        id:
          type: string
          description: TalkToHumans activity event ID.
        occurred_at:
          type: string
          format: date-time
          description: When the activity happened.
        recorded_at:
          type: string
          format: date-time
          description: When TalkToHumans recorded the activity.
        event_type:
          $ref: '#/components/schemas/ActivityEventType'
        source:
          type: string
          description: Backend emitter that recorded the fact.
          example: canonical_messages
        channel:
          type: string
          description: Activity channel when known.
          example: linkedin_message
        user_id:
          type: string
          description: TalkToHumans user ID when the fact can be attributed to a user.
        account_id:
          type: string
          description: >-
            TalkToHumans LinkedIn account ID when the fact can be attributed to
            an account.
        subject_key:
          type: string
          description: >-
            Stable content-free contact identity used to deduplicate reporting
            metrics.
        template_run_public_id:
          type: string
          description: >-
            Template-run identity when the activity belongs to attributed
            outreach.
        template_key:
          type: string
          description: >-
            Stable opaque template identity snapshotted when the activity was
            recorded.
        template_public_id:
          type: string
        template_type:
          type: string
          enum:
            - normal
            - sequence
        attribution_method:
          type: string
          enum:
            - user_and_account
            - user
            - account
            - unattributed
        metadata:
          $ref: '#/components/schemas/ActivityMetadata'
    ActivityEventType:
      type: string
      enum:
        - connection_request_sent
        - connection_request_accepted
        - incoming_connection_request_accepted
        - message_scheduled
        - message_sent
        - follow_up_sent
        - message_received
        - outbound_reply_received
        - template_run_started
        - template_run_replied
    ActivityMetadata:
      type: object
      additionalProperties:
        type: string
      description: >
        Small machine-readable metadata allowlist. Possible keys include
        `chat_provider`, `invite_entity_urn`,

        `invite_id`, `invitation_id`, `invitation_urn`, `message_mode`,
        `message_public_id`,

        `message_source`, `occurred_at_basis`, `outcome`,
        `participant_provider`, `position`,

        `previous_invite_type`, `provider_chat_id`, `provider_message_id`,
        `provider_participant_id`,

        `reason`, `relationship_source`, `reply_basis`, `scheduled_for`,
        `sequence_step_public_id`,

        `task_type`, `template_run_public_id`, and `template_status`.

        Message text, attachments, notes, drafts, and generated message bodies
        are never returned here.
    ActivityPagination:
      type: object
      additionalProperties: false
      required:
        - limit
        - has_more
      properties:
        limit:
          type: integer
          format: int32
          example: 50
        has_more:
          type: boolean
        next_cursor:
          type: string
          description: >-
            Cursor for the next activity page. Omitted when there are no more
            results.
    ListContactsEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ListContactsResponse'
    ImportContactEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ImportContactResponse'
    ImportContactResponse:
      type: object
      additionalProperties: false
      required:
        - contact
        - warnings
      properties:
        contact:
          $ref: '#/components/schemas/Contact'
        warnings:
          type: array
          description: >-
            Empty when the selected LinkedIn account is fresh; otherwise
            contains the minimal sync warning. The warning does not block
            contact import.
          items:
            $ref: '#/components/schemas/LinkedInWarning'
    ImportContactRequest:
      type: object
      additionalProperties: false
      required:
        - account_id
        - linkedin_url
      properties:
        account_id:
          type: string
          description: LinkedIn account ID returned by `GET /v1/accounts`.
          pattern: ^[1-9][0-9]*$
        linkedin_url:
          type: string
          format: uri
          description: >-
            LinkedIn member profile URL under `linkedin.com/in/`. Query
            parameters and paths after the member identifier are ignored.
          pattern: ^https?://(www\.)?linkedin\.com/in/[^/?#]+(?:[/?#].*)?$
    LinkedInWarning:
      type: object
      additionalProperties: false
      required:
        - code
        - account_id
        - message
      properties:
        code:
          type: string
          enum:
            - linkedin_sync_required
        account_id:
          type: string
          description: LinkedIn account ID that needs to sync.
        message:
          type: string
          enum:
            - >-
              For security, TalkToHumans does not run LinkedIn actions or sync
              LinkedIn data in the cloud. Open TalkToHumans with this LinkedIn
              account connected to refresh its data before relying on it or
              running actions.
    ListContactsResponse:
      type: object
      additionalProperties: false
      required:
        - contacts
        - pagination
      properties:
        contacts:
          type: array
          items:
            $ref: '#/components/schemas/Contact'
        pagination:
          $ref: '#/components/schemas/Pagination'
    CustomFieldValue:
      nullable: true
      description: >-
        Custom field value. Text fields return strings, number fields return
        numbers, boolean fields return booleans, and date fields return
        `YYYY-MM-DD` strings. Null appears only when a value is explicitly
        cleared or absent in a write response.
      oneOf:
        - type: string
        - type: number
        - type: boolean
    CustomFieldValueInput:
      nullable: true
      description: >-
        Value for a registered custom field key. Use null to clear. Date fields
        must use `YYYY-MM-DD` strings.
      oneOf:
        - type: string
        - type: number
        - type: boolean
    EnrichProfileEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/EnrichProfileResponse'
    EnrichProfileResponse:
      type: object
      additionalProperties: false
      required:
        - linkedin_enrichment
      properties:
        linkedin_enrichment:
          $ref: '#/components/schemas/LinkedInEnrichment'
    LinkedInEnrichment:
      type: object
      additionalProperties: false
      description: >-
        LinkedIn profile enrichment data. The profile is enriched first, then
        the current primary company is enriched when available.
      properties:
        profile:
          $ref: '#/components/schemas/EnrichedParticipantSnapshot'
        company:
          $ref: '#/components/schemas/EnrichedParticipantSnapshot'
    EnrichProfileRequest:
      type: object
      additionalProperties: false
      description: >
        Provide exactly one target: `contact_id`, `provider_participant_id`,
        `linkedin_url`, or `public_identifier`.
      oneOf:
        - required:
            - contact_id
        - required:
            - provider_participant_id
        - required:
            - linkedin_url
        - required:
            - public_identifier
      properties:
        account_id:
          type: string
          description: >-
            LinkedIn account ID returned by `GET /v1/accounts`. Required when
            the organization has multiple LinkedIn accounts.
          pattern: ^[1-9][0-9]*$
        contact_id:
          type: string
          description: Contact ID returned by `GET /v1/contacts`.
          pattern: ^[1-9][0-9]*$
        provider_participant_id:
          type: string
          description: LinkedIn participant ID, such as `urn:li:fsd_profile:abc`.
        linkedin_url:
          type: string
          format: uri
          description: LinkedIn profile URL.
        public_identifier:
          type: string
          description: LinkedIn public identifier from a profile URL.
        force:
          type: boolean
          description: >-
            Refresh cached enrichment data even when fresh data is already
            available.
          default: false
    EnrichedParticipantSnapshot:
      type: object
      additionalProperties: false
      required:
        - participant
        - languages
        - experiences
        - educations
        - locations
        - industries
      properties:
        participant:
          $ref: '#/components/schemas/EnrichedParticipant'
        languages:
          type: array
          items:
            $ref: '#/components/schemas/EnrichedLanguage'
        experiences:
          type: array
          items:
            $ref: '#/components/schemas/EnrichedExperience'
        educations:
          type: array
          items:
            $ref: '#/components/schemas/EnrichedEducation'
        locations:
          type: array
          items:
            $ref: '#/components/schemas/EnrichedLocation'
        industries:
          type: array
          items:
            $ref: '#/components/schemas/EnrichedIndustry'
    EnrichedParticipant:
      type: object
      additionalProperties: false
      required:
        - provider
        - provider_participant_id
        - kind
        - updated_at
      properties:
        provider:
          type: string
        provider_participant_id:
          type: string
        kind:
          type: string
          description: Participant kind, usually `member` or `company`.
        public_identifier:
          type: string
          nullable: true
        profile_url:
          type: string
          format: uri
          nullable: true
        first_name:
          type: string
          nullable: true
        last_name:
          type: string
          nullable: true
        full_name:
          type: string
          nullable: true
        headline:
          type: string
          nullable: true
        avatar_url:
          type: string
          format: uri
          nullable: true
        background_cover_url:
          type: string
          format: uri
          nullable: true
        headcount:
          type: string
          nullable: true
        employee_count:
          type: integer
          nullable: true
        founding_date:
          type: string
          nullable: true
        website_url:
          type: string
          format: uri
          nullable: true
        profile_action_label:
          type: string
          nullable: true
        profile_action_url:
          type: string
          format: uri
          nullable: true
        follower_count:
          type: integer
          nullable: true
        connections_count:
          type: integer
          nullable: true
        primary_company:
          $ref: '#/components/schemas/ParticipantKey'
        primary_company_name:
          type: string
          nullable: true
        primary_role_title:
          type: string
          nullable: true
        about:
          type: string
          nullable: true
        profile_fetched_at:
          type: string
          format: date-time
          nullable: true
        updated_at:
          type: string
          format: date-time
    ParticipantKey:
      type: object
      additionalProperties: false
      nullable: true
      required:
        - provider
        - provider_participant_id
      properties:
        provider:
          type: string
        provider_participant_id:
          type: string
    EnrichedLanguage:
      type: object
      additionalProperties: false
      required:
        - language
      properties:
        language:
          type: string
        metadata_json:
          type: string
          nullable: true
    EnrichedExperience:
      type: object
      additionalProperties: false
      required:
        - is_current
      properties:
        company:
          $ref: '#/components/schemas/ParticipantKey'
        company_name:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        employment_type:
          type: string
          nullable: true
        location:
          type: string
          nullable: true
        start_at:
          type: string
          nullable: true
        end_at:
          type: string
          nullable: true
        is_current:
          type: boolean
        description:
          type: string
          nullable: true
        metadata_json:
          type: string
          nullable: true
    EnrichedEducation:
      type: object
      additionalProperties: false
      properties:
        school:
          $ref: '#/components/schemas/ParticipantKey'
        school_name:
          type: string
          nullable: true
        degree:
          type: string
          nullable: true
        field_of_study:
          type: string
          nullable: true
        start_at:
          type: string
          nullable: true
        end_at:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        metadata_json:
          type: string
          nullable: true
    EnrichedLocation:
      type: object
      additionalProperties: false
      required:
        - source
        - sort_order
        - is_primary
        - is_headquarter
      properties:
        source:
          type: string
        sort_order:
          type: integer
          format: int32
        is_primary:
          type: boolean
        is_headquarter:
          type: boolean
        linkedin_text:
          type: string
          nullable: true
        display_text:
          type: string
          nullable: true
        country_code:
          type: string
          nullable: true
        region_code:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        country_full:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        geographic_area:
          type: string
          nullable: true
        line1:
          type: string
          nullable: true
        line2:
          type: string
          nullable: true
        postal_code:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        metadata_json:
          type: string
          nullable: true
    EnrichedIndustry:
      type: object
      additionalProperties: false
      required:
        - sort_order
      properties:
        sort_order:
          type: integer
          format: int32
        industry_urn:
          type: string
          nullable: true
        provider_industry_id:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        hierarchy:
          type: string
          nullable: true
        metadata_json:
          type: string
          nullable: true
    UpdateContactEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/UpdateContactResponse'
    UpdateContactResponse:
      type: object
      additionalProperties: false
      required:
        - contact
      properties:
        contact:
          $ref: '#/components/schemas/Contact'
    UpdateContactRequest:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/CustomFieldValueInput'
      description: >
        Contact update payload. Known system keys are documented below. Any
        additional top-level key is treated

        as a registered custom field key.
      minProperties: 1
      properties:
        account_id:
          type: string
          description: >-
            LinkedIn account ID returned by `GET /v1/accounts`. Required when
            the contact exists under multiple LinkedIn accounts.
          pattern: ^[1-9][0-9]*$
        tags:
          $ref: '#/components/schemas/ContactTagsPatch'
        notes_json:
          type: string
          nullable: true
          description: Text to store as notes. Use null or an empty string to clear notes.
    ContactTagsPatch:
      type: object
      additionalProperties: false
      description: >-
        Use `set` for exact replacement, or `add`/`remove` for incremental
        updates. `set` cannot be combined with `add` or `remove`.
      properties:
        add:
          type: array
          items:
            $ref: '#/components/schemas/ContactTagInput'
        remove:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 64
        set:
          type: array
          items:
            $ref: '#/components/schemas/ContactTagInput'
    ContactTagInput:
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 64
        color:
          type: string
          description: >-
            Supported values are green, orange, blue, red, purple, yellow, pink,
            and grey. Defaults to blue when omitted or unsupported.
    ListCompaniesEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ListCompaniesResponse'
    ListCompaniesResponse:
      type: object
      additionalProperties: false
      required:
        - companies
        - pagination
      properties:
        companies:
          type: array
          items:
            $ref: '#/components/schemas/Company'
        pagination:
          $ref: '#/components/schemas/Pagination'
    UpdateCompanyEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/UpdateCompanyResponse'
    UpdateCompanyResponse:
      type: object
      additionalProperties: false
      required:
        - company
      properties:
        company:
          $ref: '#/components/schemas/Company'
    UpdateCompanyRequest:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/CustomFieldValueInput'
      description: >
        Company update payload. Known system keys are documented below. Any
        additional top-level key is treated

        as a registered company custom field key, following the same convention
        as the contact update endpoint.

        Unknown custom field keys, keys that collide with system fields, and
        values that do not match the

        registered field type are rejected.
      minProperties: 1
      properties:
        account_id:
          type: string
          description: >-
            LinkedIn account ID returned by `GET /v1/accounts`. Required to
            write notes and when the company exists under multiple LinkedIn
            accounts.
          pattern: ^[1-9][0-9]*$
        tags:
          $ref: '#/components/schemas/ContactTagsPatch'
        notes_json:
          type: string
          nullable: true
          description: Text to store as notes. Use null or an empty string to clear notes.
    ListConversationsEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ListConversationsResponse'
    ListConversationsResponse:
      type: object
      additionalProperties: false
      required:
        - conversations
        - pagination
      properties:
        conversations:
          type: array
          items:
            $ref: '#/components/schemas/Conversation'
        pagination:
          $ref: '#/components/schemas/Pagination'
    CreateMessageDraftEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/CreateMessageDraftResponse'
    CreateMessageDraftResponse:
      type: object
      additionalProperties: false
      required:
        - draft
      properties:
        draft:
          $ref: '#/components/schemas/MessageDraft'
    CreateMessageDraftRequest:
      type: object
      additionalProperties: false
      required:
        - account_id
        - draft_message
      oneOf:
        - required:
            - conversation_id
        - required:
            - contact_id
      properties:
        account_id:
          type: string
          description: LinkedIn account ID returned by `GET /v1/accounts`.
          pattern: ^[1-9][0-9]*$
        conversation_id:
          type: string
          minLength: 1
          description: >-
            Existing conversation ID returned by `GET /v1/conversations`.
            Provide exactly one target.
        contact_id:
          type: string
          pattern: ^[1-9][0-9]*$
          description: >-
            Contact ID returned by `POST /v1/contacts` or `GET /v1/contacts`.
            Provide exactly one target.
        draft_message:
          type: string
          minLength: 1
          description: >-
            Plain-text draft. Surrounding whitespace is trimmed and the existing
            draft for the selected compose context is replaced.
    MessageDraft:
      type: object
      additionalProperties: false
      required:
        - account
        - draft_message
        - app_url
        - updated_at
      oneOf:
        - required:
            - conversation_id
        - required:
            - contact_id
      properties:
        conversation_id:
          type: string
          description: >-
            Existing TalkToHumans conversation ID when the draft targets a
            conversation.
        contact_id:
          type: string
          description: >-
            TalkToHumans contact ID when the draft targets that contact's
            compose context.
        account:
          $ref: '#/components/schemas/AccountSummary'
        draft_message:
          type: string
          description: Normalized plain-text content saved in the composer.
        app_url:
          type: string
          format: uri
          description: >-
            Opens the existing conversation or the new-message composer with the
            contact selected.
        updated_at:
          type: string
          format: date-time
    ListConversationMessagesEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ListConversationMessagesResponse'
    ListConversationMessagesResponse:
      type: object
      additionalProperties: false
      required:
        - messages
        - pagination
      properties:
        messages:
          type: array
          items:
            $ref: '#/components/schemas/ConversationMessage'
        pagination:
          $ref: '#/components/schemas/Pagination'
    ListViewsEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/ListViewsResponse'
    ListViewsResponse:
      type: object
      additionalProperties: false
      required:
        - views
        - pagination
      properties:
        views:
          type: array
          items:
            $ref: '#/components/schemas/View'
        pagination:
          $ref: '#/components/schemas/Pagination'
    View:
      type: object
      additionalProperties: false
      required:
        - id
        - public_id
        - type
        - view_kind
        - name
        - account
        - app_url
        - created_at
        - updated_at
      properties:
        id:
          type: string
          description: >-
            TalkToHumans view ID. Pass as `view_id` on `GET /v1/contacts` to
            page through its contacts.
        public_id:
          type: string
          description: >-
            Public saved-view ID used in app URLs. Also accepted as `view_id` on
            `GET /v1/contacts`.
        type:
          type: string
          enum:
            - contact
        view_kind:
          type: string
          enum:
            - member
        name:
          type: string
        description:
          type: string
          nullable: true
        account:
          $ref: '#/components/schemas/AccountSummary'
        app_url:
          type: string
          format: uri
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    CreateViewEnvelope:
      type: object
      additionalProperties: false
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/CreateViewResponse'
    CreateViewResponse:
      type: object
      additionalProperties: false
      required:
        - view
      properties:
        view:
          $ref: '#/components/schemas/CreatedView'
    CreateViewRequest:
      type: object
      additionalProperties: false
      required:
        - name
        - filters
      properties:
        account_id:
          type: string
          description: >-
            LinkedIn account ID returned by `GET /v1/accounts`. Required when
            the organization has multiple LinkedIn accounts.
          pattern: ^[1-9][0-9]*$
        type:
          type: string
          description: V1 supports contact views only.
          enum:
            - contact
            - member
          default: contact
        view_kind:
          type: string
          description: >-
            Advanced alias for the underlying TalkToHumans saved-view kind. V1
            supports `member` only.
          enum:
            - member
        name:
          type: string
          minLength: 1
          maxLength: 120
        description:
          type: string
          nullable: true
        filters:
          $ref: '#/components/schemas/CreateViewFilters'
    CreateViewFilters:
      type: object
      additionalProperties: false
      required:
        - specific_contacts
      properties:
        specific_contacts:
          $ref: '#/components/schemas/SpecificContactsFilter'
    SpecificContactsFilter:
      type: object
      additionalProperties: false
      required:
        - contact_ids
      properties:
        contact_ids:
          type: array
          minItems: 1
          maxItems: 500
          description: Contact IDs returned by `GET /v1/contacts`.
          items:
            type: string
            pattern: ^[1-9][0-9]*$
    CreatedView:
      type: object
      additionalProperties: false
      required:
        - id
        - public_id
        - type
        - view_kind
        - name
        - account
        - selected_contact_ids
        - simple_filters_json
        - app_url
        - created_at
        - updated_at
      properties:
        id:
          type: string
          description: >-
            TalkToHumans view ID. Pass as `view_id` on `GET /v1/contacts` to
            page through its contacts.
        public_id:
          type: string
          description: >-
            Public saved-view ID used in app URLs. Also accepted as `view_id` on
            `GET /v1/contacts`.
        type:
          type: string
          enum:
            - contact
        view_kind:
          type: string
          enum:
            - member
        name:
          type: string
        description:
          type: string
          nullable: true
        account:
          $ref: '#/components/schemas/AccountSummary'
        selected_contact_ids:
          type: array
          items:
            type: string
        simple_filters_json:
          type: string
          description: Serialized TalkToHumans saved-view simple filter group.
        advanced_filters_json:
          type: string
          nullable: true
          description: >-
            Serialized TalkToHumans saved-view advanced filter group. V1 returns
            null.
        app_url:
          type: string
          format: uri
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    Pagination:
      type: object
      additionalProperties: false
      required:
        - limit
        - has_more
      properties:
        limit:
          type: integer
          format: int32
          example: 10
        has_more:
          type: boolean
        next_cursor:
          type: string
          description: Cursor for the next page. Omitted when there are no more results.
    AccountSummary:
      type: object
      additionalProperties: false
      required:
        - account_id
        - display_name
        - provider_account_id
        - owner_user_id
      properties:
        account_id:
          type: string
          description: TalkToHumans account ID.
        display_name:
          type: string
        provider_account_id:
          type: string
          description: LinkedIn provider account ID.
        owner_user_id:
          type: string
          description: TalkToHumans user ID that owns the account.
    Contact:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/CustomFieldValue'
      description: >
        LinkedIn contact. Registered custom field values may appear as
        additional top-level properties using

        each custom field's `key`, alongside the system fields documented below.
      required:
        - account_relationship_id
        - contact_id
        - provider_participant_id
        - account
        - name
        - relationship_status
        - tags
        - languages
        - experiences
        - educations
        - locations
        - app_url
      properties:
        account_relationship_id:
          type: string
        contact_id:
          type: string
          description: TalkToHumans contact ID.
        provider_participant_id:
          type: string
          description: LinkedIn participant ID.
        public_identifier:
          type: string
        account:
          $ref: '#/components/schemas/AccountSummary'
        name:
          type: string
        first_name:
          type: string
        last_name:
          type: string
        headline:
          type: string
        primary_role_title:
          type: string
        primary_company_name:
          type: string
        work_email:
          type: string
          description: Work email when email enrichment was found for this organization.
        phone:
          type: string
          description: Phone number when phone enrichment was found for this organization.
        linkedin_url:
          type: string
          format: uri
        avatar_url:
          type: string
          format: uri
        background_cover_url:
          type: string
          format: uri
        about:
          type: string
        profile_action_label:
          type: string
        profile_action_url:
          type: string
          format: uri
        follower_count:
          type: integer
          nullable: true
        connections_count:
          type: integer
          nullable: true
        relationship_status:
          $ref: '#/components/schemas/RelationshipStatus'
        connection_invitation:
          $ref: '#/components/schemas/ConnectionInvitation'
        tags:
          type: array
          items:
            $ref: '#/components/schemas/APITag'
        notes_json:
          type: string
          description: Notes.
        languages:
          type: array
          items:
            $ref: '#/components/schemas/Language'
        experiences:
          type: array
          items:
            $ref: '#/components/schemas/Experience'
        educations:
          type: array
          items:
            $ref: '#/components/schemas/Education'
        locations:
          type: array
          items:
            $ref: '#/components/schemas/Location'
        company:
          $ref: '#/components/schemas/Company'
        last_interaction_at:
          type: string
          format: date-time
          nullable: true
        sequence:
          $ref: '#/components/schemas/Sequence'
        app_url:
          type: string
          format: uri
    Conversation:
      type: object
      additionalProperties: false
      required:
        - conversation_id
        - account
        - title
        - is_group
        - participants
        - app_url
      properties:
        conversation_id:
          type: string
          description: TalkToHumans conversation ID.
        account:
          $ref: '#/components/schemas/AccountSummary'
        title:
          type: string
        is_group:
          type: boolean
        participants:
          type: array
          items:
            $ref: '#/components/schemas/ConversationParticipant'
        last_message_text:
          type: string
        last_message_direction:
          type: string
          enum:
            - sent
            - received
            - ''
        last_message_at:
          type: string
          format: date-time
          nullable: true
        current_state:
          type: string
        sequence:
          $ref: '#/components/schemas/Sequence'
        app_url:
          type: string
          format: uri
    ConversationParticipant:
      type: object
      additionalProperties: false
      required:
        - contact_id
        - provider_participant_id
        - name
        - relationship_status
      properties:
        account_relationship_id:
          type: string
        contact_id:
          type: string
        provider_participant_id:
          type: string
        public_identifier:
          type: string
        name:
          type: string
        first_name:
          type: string
        last_name:
          type: string
        headline:
          type: string
        primary_role_title:
          type: string
        primary_company_name:
          type: string
        linkedin_url:
          type: string
          format: uri
        avatar_url:
          type: string
          format: uri
        relationship_status:
          $ref: '#/components/schemas/RelationshipStatus'
    ConversationMessage:
      type: object
      additionalProperties: false
      required:
        - message_id
        - provider_message_id
        - conversation_id
        - direction
        - sent_at
        - is_edited
        - is_deleted
        - attachments
      properties:
        message_id:
          type: string
          description: TalkToHumans message ID.
        provider_message_id:
          type: string
          description: LinkedIn provider message ID.
        conversation_id:
          type: string
          description: TalkToHumans conversation ID.
        text:
          type: string
        direction:
          type: string
          enum:
            - sent
            - received
        sent_at:
          type: string
          format: date-time
        is_edited:
          type: boolean
        is_deleted:
          type: boolean
        sender_participant_id:
          type: string
          description: LinkedIn participant ID for the sender when available.
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/ConversationMessageAttachment'
    ConversationMessageAttachment:
      type: object
      additionalProperties: false
      required:
        - attachment_id
        - kind
        - sort_order
      properties:
        attachment_id:
          type: string
          description: TalkToHumans attachment ID.
        provider_attachment_id:
          type: string
          description: LinkedIn provider attachment ID.
        kind:
          type: string
        sort_order:
          type: integer
          format: int32
        title:
          type: string
        subtitle:
          type: string
        description:
          type: string
        url:
          type: string
          format: uri
        thumbnail_url:
          type: string
          format: uri
        mime_type:
          type: string
        file_name:
          type: string
        size_bytes:
          type: integer
          format: int32
        width:
          type: integer
          format: int32
        height:
          type: integer
          format: int32
        duration_ms:
          type: integer
          format: int32
    RelationshipStatus:
      type: string
      enum:
        - connected
        - not_connected
        - unknown
    ConnectionInvitation:
      type: object
      additionalProperties: false
      nullable: true
      required:
        - status
        - direction
      properties:
        status:
          type: string
          enum:
            - pending
        direction:
          type: string
          enum:
            - incoming
            - outgoing
            - unknown
        invite_id:
          type: string
        invite_state:
          type: string
        invite_type:
          type: string
        received_at:
          type: string
          format: date-time
          nullable: true
    APITag:
      type: object
      additionalProperties: false
      required:
        - name
        - color
      properties:
        name:
          type: string
        color:
          type: string
          enum:
            - green
            - orange
            - blue
            - red
            - purple
            - yellow
            - pink
            - grey
    Language:
      type: object
      additionalProperties: false
      required:
        - language
      properties:
        language:
          type: string
    Experience:
      type: object
      additionalProperties: false
      required:
        - experience_id
        - is_current
      properties:
        experience_id:
          type: string
        company_participant_id:
          type: string
        company_provider_participant_id:
          type: string
        company_name:
          type: string
        title:
          type: string
        employment_type:
          type: string
        location:
          type: string
        start_at:
          type: string
        end_at:
          type: string
        is_current:
          type: boolean
        description:
          type: string
    Education:
      type: object
      additionalProperties: false
      required:
        - education_id
      properties:
        education_id:
          type: string
        school_participant_id:
          type: string
        school_provider_participant_id:
          type: string
        school_name:
          type: string
        degree:
          type: string
        field_of_study:
          type: string
        start_at:
          type: string
        end_at:
          type: string
        description:
          type: string
    Location:
      type: object
      additionalProperties: false
      required:
        - is_primary
        - is_headquarter
      properties:
        linkedin_text:
          type: string
        display_text:
          type: string
        country_code:
          type: string
        region_code:
          type: string
        country:
          type: string
        country_full:
          type: string
        state:
          type: string
        city:
          type: string
        geographic_area:
          type: string
        is_primary:
          type: boolean
        is_headquarter:
          type: boolean
    Industry:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
        title:
          type: string
        industry_urn:
          type: string
        provider_industry_id:
          type: string
        hierarchy:
          type: string
    Company:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/CustomFieldValue'
      description: |
        A company.
      nullable: true
      required:
        - company_id
        - provider_participant_id
        - name
        - industries
        - locations
      properties:
        company_id:
          type: string
        provider_participant_id:
          type: string
        public_identifier:
          type: string
        name:
          type: string
        headline:
          type: string
        linkedin_url:
          type: string
          format: uri
        avatar_url:
          type: string
          format: uri
        background_cover_url:
          type: string
          format: uri
        headcount:
          type: string
        employee_count:
          type: integer
          nullable: true
        founding_date:
          type: string
        website_url:
          type: string
          format: uri
        follower_count:
          type: integer
          nullable: true
        about:
          type: string
        notes_json:
          type: string
          description: Notes
        industries:
          type: array
          items:
            $ref: '#/components/schemas/Industry'
        locations:
          type: array
          items:
            $ref: '#/components/schemas/Location'
        tags:
          type: array
          description: Tags
          items:
            $ref: '#/components/schemas/APITag'
    Sequence:
      type: object
      additionalProperties: false
      nullable: true
      required:
        - sequence_id
        - status
        - stop_if_person_replies
        - steps
      properties:
        sequence_id:
          type: string
        status:
          type: string
        stop_if_person_replies:
          type: boolean
        reply_guard_after:
          type: string
          format: date-time
          nullable: true
        next_step_id:
          type: string
        next_step_scheduled_for:
          type: string
          format: date-time
          nullable: true
        steps:
          type: array
          items:
            $ref: '#/components/schemas/SequenceStep'
    SequenceStep:
      type: object
      additionalProperties: false
      required:
        - step_id
        - step_type
        - trigger_type
        - position
        - message_mode
        - state
      properties:
        step_id:
          type: string
        template_run_public_id:
          type: string
        step_type:
          type: string
        trigger_type:
          type: string
        position:
          type: integer
          format: int32
        scheduled_for:
          type: string
          format: date-time
          nullable: true
        message_mode:
          type: string
        state:
          type: string
