openapi: 3.1.0
info:
  title: Up2Data API
  version: 1.0.0
  description: >
    Fresh B2B data, at scale. Real-time LinkedIn profile, company, search, jobs
    and posts data through one usage-based API — plus Signals, criteria-based
    change monitoring. Every scrape runs live (never cached). Enrichment is
    pay-on-success; Signal checks are pay-per-check. Credit costs are declared
    per operation via the x-credits extension.
  contact:
    email: support@up2data.ai
    url: https://docs.up2data.ai
servers:
  - url: https://api.up2data.ai
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Profiles
  - name: Companies
  - name: Search
  - name: Jobs
  - name: Posts
  - name: Batch
  - name: Signals
  - name: Triggers
  - name: Account
paths:
  /v1/profiles/enrich:
    post:
      tags:
        - Profiles
      operationId: enrichProfile
      summary: Enrich a profile
      description: >-
        Turn any profile URL into a full live record, scraped at request time.
        Pure profile scraping — no email finding.
      x-credits: 1 per successful profile
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              properties:
                url:
                  type: string
                  description: Public profile URL or public identifier.
                  examples:
                    - https://linkedin.com/in/satyanadella
                fields:
                  type: array
                  items:
                    type: string
                  description: Restrict response to these top-level fields. Same cost.
      responses:
        '200':
          description: Profile found and billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Profile'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v1/batch:
    post:
      tags:
        - Batch
      operationId: createBatchJob
      summary: Create a batch job (async)
      description: >
        Async fan-out for up to 1,000 operations per job. Submit enrichment
        targets (profile, company, post URLs) and/or batchable API operations
        (e.g. multiple people searches with different filters). Each item bills
        at that operation's normal credit rate as it resolves.
      x-credits: per item, at the entity's normal cost; submission free
      x-price-per-1k-at-volume-usd: 2
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
          description: Retried submissions with the same key return the original job.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  type: array
                  maxItems: 1000
                  items:
                    $ref: '#/components/schemas/BatchItem'
                webhook_url:
                  type: string
                  description: HTTPS endpoint for the batch.completed event.
      responses:
        '202':
          description: Job accepted (not billed).
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/BatchJob'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/batch/{job_id}:
    get:
      tags:
        - Batch
      operationId: getBatchJob
      summary: Get a batch job
      description: Poll an async job. Free.
      x-credits: free
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Job status and (when completed) full results.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/BatchJobResult'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '404':
          $ref: '#/components/responses/NotFound'
  /v1/posts/enrich:
    post:
      tags:
        - Posts
      operationId: enrichPost
      summary: Enrich a post
      description: >-
        Fetch one post by URL — full text and live engagement, scraped at
        request time.
      x-credits: 1 per successful post
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: Public post URL.
                urn:
                  type: string
                  description: Post activity URN (numeric). Preferred when available.
              anyOf:
                - required:
                    - url
                - required:
                    - urn
      responses:
        '200':
          description: Post found and billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Post'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/companies/enrich:
    post:
      tags:
        - Companies
      operationId: enrichCompany
      summary: Enrich a company
      description: Live firmographics — headcount as of right now.
      x-credits: 1 per successful company
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/CompanyLookup'
                - type: object
                  properties:
                    fields:
                      type: array
                      items:
                        type: string
                      description: Restrict response to these top-level fields. Same cost.
      responses:
        '200':
          description: Company found and billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Company'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/search/people:
    post:
      tags:
        - Search
      operationId: searchPeople
      summary: Search people
      description: >
        Live people search. Pass structured `filters` (Up2Data builds the
        LinkedIn search URL) or paste a classic LinkedIn `search_url`. Exactly
        one of `filters` or `search_url` is required. Set `max_results` and
        Up2Data paginates until that many profile stubs are returned or results
        are exhausted.
      x-credits: 2 per page scraped (up to 25 results per page); empty pages free
      x-price-per-1k-at-volume-usd: 4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                filters:
                  $ref: '#/components/schemas/PeopleSearchFilters'
                search_url:
                  type: string
                  description: >
                    Classic LinkedIn people search URL. Mutually exclusive with
                    filters.
                max_results:
                  type: integer
                  default: 25
                  minimum: 1
                  maximum: 1000
                  description: >-
                    Target number of profile stubs to return. Up2Data paginates
                    internally.
              oneOf:
                - required:
                    - filters
                - required:
                    - search_url
      responses:
        '200':
          description: Profile stubs up to max_results.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      results:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProfileStub'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/search/jobs:
    post:
      tags:
        - Search
      operationId: searchJobs
      summary: Search jobs
      description: >
        Live job postings by company or keyword. Set `max_results` and Up2Data
        paginates internally until that many jobs are returned or results are
        exhausted.
      x-credits: 1 per job returned; zero-result queries free
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                company_url:
                  type: string
                keywords:
                  type: array
                  items:
                    type: string
                filters:
                  type: object
                  properties:
                    locations:
                      type: array
                      items:
                        type: string
                    seniority:
                      type: array
                      items:
                        type: string
                        enum:
                          - entry
                          - senior
                          - manager
                          - director
                          - executive
                    function:
                      type: array
                      items:
                        type: string
                    workplace_type:
                      type: array
                      items:
                        type: string
                        enum:
                          - remote
                          - hybrid
                          - onsite
                    posted_within_days:
                      type: integer
                max_results:
                  type: integer
                  default: 25
                  minimum: 1
                  maximum: 100
                  description: >-
                    Target number of jobs to return. Up2Data paginates
                    internally.
      responses:
        '200':
          description: Matching jobs.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      jobs:
                        type: array
                        items:
                          $ref: '#/components/schemas/JobPosting'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/search/posts:
    post:
      tags:
        - Search
      operationId: searchPosts
      summary: Search posts
      description: >
        Live post search by keyword, hashtag, or author feed. Set `max_results`
        and Up2Data paginates internally until that many posts are returned or
        results are exhausted.
      x-credits: 2 per page scraped (up to 25 posts per page); zero-result pages free
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                keywords:
                  type: array
                  items:
                    type: string
                hashtags:
                  type: array
                  items:
                    type: string
                author_url:
                  type: string
                author_urn:
                  type: string
                posted_within:
                  type: string
                  enum:
                    - 24h
                    - week
                    - month
                    - all
                  default: all
                sort:
                  type: string
                  enum:
                    - recent
                    - top
                    - relevance
                  default: recent
                max_results:
                  type: integer
                  default: 25
                  minimum: 1
                  maximum: 100
                  description: >-
                    Target number of posts to return. Up2Data paginates
                    internally.
      responses:
        '200':
          description: Matching posts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      posts:
                        type: array
                        items:
                          $ref: '#/components/schemas/Post'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/profiles/recommendations:
    post:
      tags:
        - Profiles
      operationId: getProfileRecommendations
      summary: Get profile recommendations
      description: >
        One endpoint with a `direction` parameter — not separate /given and
        /received routes. Each direction (`given`, `received`) is a separate
        scrape; pass `direction: both` to fetch both lists in one HTTP call
        (billed as two scrapes).
      x-credits: 1 per direction scraped; direction both = 2 credits
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/ProfileLookup'
                - type: object
                  properties:
                    direction:
                      type: string
                      enum:
                        - given
                        - received
                        - both
                      default: both
                      description: >-
                        Which recommendation lists to scrape. `given` and
                        `received` are separate scrapes; `both` runs both in one
                        request.
                    page:
                      type: integer
                      default: 1
                      minimum: 1
                    per_page:
                      type: integer
                      default: 10
                      minimum: 1
                      maximum: 25
      responses:
        '200':
          description: Recommendations returned and billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ProfileRecommendations'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/companies/insights:
    post:
      tags:
        - Companies
      operationId: getCompanyInsights
      summary: Get company insights
      description: Headcount breakdowns, growth trends, and hiring signals for a company.
      x-credits: 5 per successful company
      x-price-per-1k-at-volume-usd: 10
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompanyLookup'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CompanyInsights'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/companies/jobs-count:
    post:
      tags:
        - Companies
      operationId: getCompanyJobsCount
      summary: Count company job openings
      description: Return the number of active job postings a company has on LinkedIn.
      x-credits: 1 per successful lookup
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompanyLookup'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CompanyJobsCount'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/companies/posts:
    post:
      tags:
        - Companies
      operationId: getCompanyPosts
      summary: Get company posts
      description: >-
        List recent posts published by a company page. Companies have no public
        comments/reactions activity feed — authored posts only.
      x-credits: 2 per page (up to 25 posts); empty pages free
      x-price-per-1k-at-volume-usd: 4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/CompanyLookup'
                - type: object
                  properties:
                    page:
                      type: integer
                      default: 1
                      minimum: 1
                    per_page:
                      type: integer
                      default: 25
                      minimum: 1
                      maximum: 25
                    pagination_token:
                      type: string
                      description: >-
                        Required for pages after the first when returned by a
                        prior response.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      posts:
                        type: array
                        items:
                          $ref: '#/components/schemas/Post'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                      pagination_token:
                        type:
                          - string
                          - 'null'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/companies/headcount:
    post:
      tags:
        - Companies
      operationId: findCustomHeadcount
      summary: Find custom headcount
      description: >-
        Count employees at a company matching title, seniority, location, or
        keyword filters.
      x-credits: 1 per successful query
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - company_url
                - filters
              properties:
                company_url:
                  type: string
                filters:
                  type: object
                  properties:
                    titles:
                      type: array
                      items:
                        type: string
                    seniorities:
                      type: array
                      items:
                        type: string
                        enum:
                          - owner
                          - partner
                          - cxo
                          - vp
                          - director
                          - manager
                          - senior
                          - entry
                    locations:
                      type: array
                      items:
                        type: string
                    keywords:
                      type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CompanyHeadcountResult'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/search/companies:
    post:
      tags:
        - Search
      operationId: searchCompanies
      summary: Search companies
      description: >
        Live company search. Pass structured `filters` (Up2Data builds the
        LinkedIn search URL) or paste a classic LinkedIn `search_url`. Exactly
        one of `filters` or `search_url` is required.
      x-credits: 2 per page scraped (up to 25 results per page); empty pages free
      x-price-per-1k-at-volume-usd: 4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                filters:
                  $ref: '#/components/schemas/CompanySearchFilters'
                search_url:
                  type: string
                  description: >
                    Classic LinkedIn company search URL. Mutually exclusive with
                    filters.
                max_results:
                  type: integer
                  default: 25
                  minimum: 1
                  maximum: 1000
                  description: >-
                    Target number of company stubs to return. Up2Data paginates
                    internally.
              oneOf:
                - required:
                    - filters
                - required:
                    - search_url
      responses:
        '200':
          description: Company stubs up to max_results.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      results:
                        type: array
                        items:
                          $ref: '#/components/schemas/CompanyStub'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/search/companies/sales-nav:
    post:
      tags:
        - Search
      operationId: searchCompaniesBySalesNav
      summary: Search companies (Sales Navigator)
      description: >
        Sales Navigator company search. Pass structured `filters` (Up2Data
        builds the SN URL) or paste a `sales_nav_url`. Exactly one is required.
      x-credits: 2 per page scraped (up to 25 results per page); empty pages free
      x-price-per-1k-at-volume-usd: 4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                filters:
                  $ref: '#/components/schemas/CompanySearchFilters'
                sales_nav_url:
                  type: string
                  description: Full SN company search URL. Mutually exclusive with filters.
                max_results:
                  type: integer
                  default: 25
                  minimum: 1
                  maximum: 1000
                  description: >-
                    Target number of company stubs to return. Up2Data paginates
                    internally.
              oneOf:
                - required:
                    - filters
                - required:
                    - sales_nav_url
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      results:
                        type: array
                        items:
                          $ref: '#/components/schemas/CompanyStub'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/search/people/sales-nav:
    post:
      tags:
        - Search
      operationId: searchPeopleBySalesNav
      summary: Search people (Sales Navigator)
      description: >
        Sales Navigator people search. Pass structured `filters` (Up2Data builds
        the SN URL) or paste a `sales_nav_url`. Exactly one is required. Geo,
        industry, company, and school filters take LinkedIn IDs
        (client-supplied).
      x-credits: 2 per page scraped (up to 25 results per page); empty pages free
      x-price-per-1k-at-volume-usd: 4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                filters:
                  $ref: '#/components/schemas/PeopleSearchFilters'
                sales_nav_url:
                  type: string
                  description: Full SN people search URL. Mutually exclusive with filters.
                max_results:
                  type: integer
                  default: 25
                  minimum: 1
                  maximum: 1000
                  description: >-
                    Target number of profile stubs to return. Up2Data paginates
                    internally.
              oneOf:
                - required:
                    - filters
                - required:
                    - sales_nav_url
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      results:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProfileStub'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/jobs/enrich:
    post:
      tags:
        - Jobs
      operationId: enrichJob
      summary: Enrich a job
      description: >-
        Fetch full details for a single job posting, including description and
        company snapshot.
      x-credits: 1 per successful job
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: Public job posting URL.
                job_id:
                  type: string
                  description: LinkedIn job ID if URL is unavailable.
              anyOf:
                - required:
                    - url
                - required:
                    - job_id
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/JobDetail'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/posts/engagement/comments:
    post:
      tags:
        - Posts
      operationId: getPostComments
      summary: Get post comments
      description: >-
        Inbound engagement on a post — who commented. Distinct from profile
        outbound activity (`/v1/profiles/activity` with `kind: comments`).
      x-credits: 1 per page (up to 25 comments); empty pages free
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostEngagementLookup'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      comments:
                        type: array
                        items:
                          $ref: '#/components/schemas/PostComment'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/posts/engagement/reactions:
    post:
      tags:
        - Posts
      operationId: getPostReactions
      summary: Get post reactions
      description: >-
        Inbound engagement on a post — who reacted. Distinct from profile
        outbound activity (`/v1/profiles/activity` with `kind: reactions`).
      x-credits: 1 per page (up to 25 reactions); empty pages free
      x-price-per-1k-at-volume-usd: 2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/PostEngagementLookup'
                - type: object
                  properties:
                    reaction_type:
                      type: string
                      enum:
                        - ALL
                        - LIKE
                        - EMPATHY
                        - APPRECIATION
                        - INTEREST
                        - PRAISE
                      default: ALL
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      reactions:
                        type: array
                        items:
                          $ref: '#/components/schemas/PostReaction'
                      pagination:
                        $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/profiles/activity:
    post:
      tags:
        - Profiles
      operationId: getProfileActivity
      summary: Get profile activity
      description: >-
        Outbound activity for a profile — what they published, commented on,
        reacted to, or reposted. Pass exactly one `kind` per request; each kind
        triggers a separate LinkedIn scrape and is billed independently. There
        is no combined `all` mode.
      x-credits: 2 per page (up to 25 items); empty pages free — one kind per request
      x-price-per-1k-at-volume-usd: 4
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileActivityRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ProfileActivityResult'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '422':
          $ref: '#/components/responses/UnprocessableTarget'
  /v1/signals/bulk:
    post:
      tags:
        - Signals
      operationId: bulkCreateSignals
      summary: Bulk create Signals
      description: One template × up to 1,000 targets → N Signals in one call.
      x-credits: free to create; each Signal's checks bill per pay-per-check rules
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - template
                - targets
              properties:
                template:
                  type: object
                  required:
                    - schedule
                    - criteria
                  properties:
                    name_prefix:
                      type: string
                    tags:
                      type: array
                      items:
                        type: string
                    schedule:
                      $ref: '#/components/schemas/Schedule'
                    criteria:
                      $ref: '#/components/schemas/Criteria'
                    notify:
                      $ref: '#/components/schemas/Notify'
                targets:
                  type: array
                  maxItems: 1000
                  items:
                    $ref: '#/components/schemas/Target'
      responses:
        '201':
          description: Fleet created (invalid targets itemized in rejected[]).
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      created:
                        type: integer
                      rejected:
                        type: array
                        items:
                          type: object
                          properties:
                            linkedin_url:
                              type: string
                            reason:
                              type: string
                      estimated_monthly_credits:
                        type: integer
                      signals:
                        type: array
                        items:
                          $ref: '#/components/schemas/Signal'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/signals/pause:
    post:
      tags:
        - Signals
      operationId: bulkPauseSignals
      summary: Bulk pause Signals by tag
      x-credits: free
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - tag
              properties:
                tag:
                  type: string
      responses:
        '200':
          description: Count of Signals paused.
  /v1/signals/resume:
    post:
      tags:
        - Signals
      operationId: bulkResumeSignals
      summary: Bulk resume Signals by tag
      x-credits: free
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - tag
              properties:
                tag:
                  type: string
      responses:
        '200':
          description: Count of Signals resumed.
  /v1/signals:
    post:
      tags:
        - Signals
      operationId: createSignal
      summary: Create a Signal
      description: >
        Define what to watch, how often, and where to get pinged. Creation is
        free; every scheduled check bills the underlying scrape (pay-per-check),
        whether or not it triggers. Failed scrapes are never billed.
      x-credits: free to create; each check bills the underlying scrape
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignalInput'
      responses:
        '201':
          description: Signal created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Signal'
                  meta:
                    $ref: '#/components/schemas/Meta'
    get:
      tags:
        - Signals
      operationId: listSignals
      summary: List Signals
      x-credits: free
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum:
              - active
              - paused
        - name: target_type
          in: query
          schema:
            type: string
            enum:
              - profile
              - profile_list
              - company
              - company_jobs
              - post
              - post_search
              - people_search
        - name: tag
          in: query
          schema:
            type: string
        - name: cursor
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 100
      responses:
        '200':
          description: Signals on the account.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Signal'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/signals/{id}:
    get:
      tags:
        - Signals
      operationId: getSignal
      summary: Get a Signal
      description: >-
        Full state including status, next_check_at and
        estimated_monthly_credits.
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: The Signal.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Signal'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      tags:
        - Signals
      operationId: updateSignal
      summary: Update a Signal
      description: Partial update — schedule, criteria, notify. Snapshot history preserved.
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignalInput'
      responses:
        '200':
          description: Updated Signal.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Signal'
                  meta:
                    $ref: '#/components/schemas/Meta'
    delete:
      tags:
        - Signals
      operationId: deleteSignal
      summary: Delete a Signal
      description: Immediate. Trigger history is retained for the plan's retention window.
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Deleted.
  /v1/signals/{id}/pause:
    post:
      tags:
        - Signals
      operationId: pauseSignal
      summary: Pause a Signal
      description: >-
        Stops checks; snapshot kept so a change while paused still triggers on
        resume.
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Paused.
  /v1/signals/{id}/resume:
    post:
      tags:
        - Signals
      operationId: resumeSignal
      summary: Resume a Signal
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Active again; next_check_at rescheduled.
  /v1/signals/{id}/test:
    post:
      tags:
        - Signals
      operationId: testSignal
      summary: Test a Signal (run one check now)
      description: >-
        Same billing rules as a scheduled check. Real Trigger + webhook on
        match.
      x-credits-per-check: same as the Signal's underlying scrape
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Check result (matched or not) with cost.
  /v1/signals/{id}/triggers:
    get:
      tags:
        - Triggers
      operationId: listSignalTriggers
      summary: List Triggers for one Signal
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: since
          in: query
          schema:
            type: string
            format: date-time
        - name: matched
          in: query
          schema:
            type: boolean
          description: Include unmatched check logs when false.
        - name: cursor
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 100
      responses:
        '200':
          description: Triggers for the Signal.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Trigger'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/triggers:
    get:
      tags:
        - Triggers
      operationId: listTriggers
      summary: List Triggers across all Signals
      x-credits: free
      parameters:
        - name: signal_id
          in: query
          schema:
            type: string
        - name: tag
          in: query
          schema:
            type: string
          description: Only Triggers from Signals carrying this tag.
        - name: since
          in: query
          schema:
            type: string
            format: date-time
        - name: matched
          in: query
          schema:
            type: boolean
          description: Include unmatched check logs when false.
        - name: cursor
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 100
      responses:
        '200':
          description: Trigger history.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Trigger'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /v1/triggers/{id}:
    get:
      tags:
        - Triggers
      operationId: getTrigger
      summary: Get a Trigger
      description: Full diff, full entity snapshot, and webhook delivery status.
      x-credits: free
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: The Trigger.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Trigger'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '404':
          $ref: '#/components/responses/NotFound'
  /v1/account:
    patch:
      tags:
        - Account
      operationId: updateAccount
      summary: Update account settings
      description: Default notification settings and the monitoring budget cap.
      x-credits: free
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                monitoring:
                  type: object
                  properties:
                    default_webhook_url:
                      type: string
                    default_webhook_secret:
                      type: string
                      writeOnly: true
                    monthly_check_budget:
                      type:
                        - integer
                        - 'null'
                      description: >-
                        Hard monthly cap (credits) on Signal check spend; null
                        for no cap.
      responses:
        '200':
          description: Updated settings.
    get:
      tags:
        - Account
      operationId: getAccount
      summary: Get account
      description: Balance, tier, rate limits, Signal spend. Free.
      x-credits: free
      responses:
        '200':
          description: Account state.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Account'
                  meta:
                    $ref: '#/components/schemas/Meta'
webhooks:
  signal.triggered:
    post:
      summary: A Signal check matched its criteria
      description: >
        Signed with X-Up2Data-Signature (HMAC-SHA256 over
        "{timestamp}.{raw_body}" using the Signal's webhook_secret). Retried 5
        times with exponential backoff; deliveries are idempotent by trigger_id.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignalTriggeredEvent'
      responses:
        '200':
          description: Return any 2xx within 10s to acknowledge.
  signal.paused:
    post:
      summary: A Signal was auto-paused
      description: Fired on insufficient credits or repeated webhook delivery failure.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                event:
                  type: string
                  const: signal.paused
                signal:
                  $ref: '#/components/schemas/Signal'
                paused_reason:
                  type: string
                  enum:
                    - insufficient_credits
                    - webhook_failing
      responses:
        '200':
          description: Acknowledge.
  signal.check.failed:
    post:
      summary: A scheduled check's scrape failed (not billed)
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                event:
                  type: string
                  const: signal.check.failed
                signal_id:
                  type: string
                checked_at:
                  type: string
                  format: date-time
                error_type:
                  type: string
      responses:
        '200':
          description: Acknowledge.
  batch.completed:
    post:
      summary: An async enrichment job finished
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                event:
                  type: string
                  const: batch.completed
                job:
                  $ref: '#/components/schemas/BatchJob'
      responses:
        '200':
          description: Acknowledge.
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Live keys: u2d_live_… Sandbox keys: u2d_test_… (fixture data, never
        billed).
  responses:
    UnprocessableTarget:
      description: Target private, deleted, or unreachable. Not billed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Resource does not exist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Over the tier's request limit. Honor Retry-After. Not billed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Meta:
      type: object
      description: Billing metadata on every response.
      properties:
        creditsUsed:
          type: integer
        creditsRemaining:
          type: integer
        billed:
          type: boolean
        reason:
          type: string
        requestId:
          type: string
        latencyMs:
          type: integer
        nextCursor:
          type:
            - string
            - 'null'
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              enum:
                - invalid_request
                - invalid_api_key
                - insufficient_credits
                - not_found
                - unprocessable_target
                - rate_limited
                - internal_error
                - upstream_timeout
            message:
              type: string
            requestId:
              type: string
    Profile:
      type: object
      properties:
        url:
          type: string
        public_identifier:
          type: string
        full_name:
          type: string
        headline:
          type: string
        location:
          type: object
          properties:
            city:
              type: string
            region:
              type: string
            country:
              type: string
        current_company:
          type: object
          properties:
            name:
              type: string
            url:
              type: string
            title:
              type: string
            started_at:
              type: string
        positions:
          type: array
          items:
            type: object
            properties:
              title:
                type: string
              company:
                type: string
              company_url:
                type: string
              started_at:
                type: string
              ended_at:
                type:
                  - string
                  - 'null'
              description:
                type: string
        education:
          type: array
          items:
            type: object
            properties:
              school:
                type: string
              degree:
                type: string
              field:
                type: string
        skills:
          type: array
          items:
            type: string
        about:
          type: string
        email:
          type: string
        phone:
          type: string
        urn:
          type: string
        languages:
          type: array
          items:
            type: string
        certifications:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              authority:
                type: string
              issued_at:
                type: string
        publications:
          type: array
          items:
            type: object
            properties:
              title:
                type: string
              publisher:
                type: string
              published_at:
                type: string
              url:
                type: string
        patents:
          type: array
          items:
            type: object
            properties:
              title:
                type: string
              number:
                type: string
              issued_at:
                type: string
        awards:
          type: array
          items:
            type: object
            properties:
              title:
                type: string
              issuer:
                type: string
              issued_at:
                type: string
        is_premium:
          type: boolean
        is_verified:
          type: boolean
        is_open_profile:
          type: boolean
        is_open_to_work:
          type: boolean
        job_preferences:
          type:
            - object
            - 'null'
          description: Visible when is_open_to_work is true.
          properties:
            titles:
              type: array
              items:
                type: string
            locations:
              type: array
              items:
                type: string
            workplace_types:
              type: array
              items:
                type: string
                enum:
                  - remote
                  - hybrid
                  - onsite
            start_timing:
              type: string
        connections_count:
          type: integer
        followers_count:
          type: integer
        scraped_at:
          type: string
          format: date-time
    ProfileStub:
      type: object
      properties:
        url:
          type: string
        public_identifier:
          type: string
        urn:
          type: string
        full_name:
          type: string
        headline:
          type: string
        location:
          type: object
          properties:
            city:
              type: string
            country:
              type: string
        current_company:
          type: object
          properties:
            name:
              type: string
            url:
              type: string
    Company:
      type: object
      properties:
        url:
          type: string
        name:
          type: string
        website:
          type: string
        description:
          type: string
        industry:
          type: string
        headcount:
          type: integer
        headcount_growth_6m:
          type: number
        company_size:
          type: object
          properties:
            min:
              type: integer
            max:
              type: integer
        founded:
          type: integer
        hq:
          type: object
          properties:
            city:
              type: string
            region:
              type: string
            country:
              type: string
        locations:
          type: array
          items:
            type: object
        specialties:
          type: array
          items:
            type: string
        funding:
          type: object
          properties:
            total_usd:
              type: integer
            last_round:
              type: object
              properties:
                type:
                  type: string
                amount_usd:
                  type: integer
                date:
                  type: string
        followers_count:
          type: integer
        scraped_at:
          type: string
          format: date-time
    JobPosting:
      type: object
      properties:
        url:
          type: string
        title:
          type: string
        company:
          type: object
          properties:
            name:
              type: string
            url:
              type: string
        location:
          type: string
        workplace_type:
          type: string
          enum:
            - remote
            - hybrid
            - onsite
        seniority:
          type: string
        posted_at:
          type: string
          format: date-time
        applicants_count:
          type: integer
        description_snippet:
          type: string
    Post:
      type: object
      properties:
        url:
          type: string
        author:
          type: object
          properties:
            name:
              type: string
            url:
              type: string
            headline:
              type: string
        text:
          type: string
        posted_at:
          type: string
          format: date-time
        reactions_count:
          type: integer
        comments_count:
          type: integer
        reposts_count:
          type: integer
        urn:
          type: string
        share_urn:
          type: string
        scraped_at:
          type: string
          format: date-time
        media:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                enum:
                  - image
                  - video
                  - document
              url:
                type: string
    Pagination:
      type: object
      properties:
        returned:
          type: integer
          description: Records returned in this response (search endpoints).
        max_results:
          type: integer
          description: The max_results cap from a search request.
        pages_scraped:
          type: integer
          description: >-
            LinkedIn result pages scraped to build this response (search
            endpoints).
        page:
          type: integer
          description: Current page when paginating feeds client-side.
        per_page:
          type: integer
          description: Page size when paginating feeds client-side.
        has_more:
          type: boolean
          description: True if more results exist beyond this response.
        total_estimate:
          type: integer
    Schedule:
      type: object
      required:
        - interval
      properties:
        interval:
          type: string
          enum:
            - 15m
            - 1h
            - 6h
            - 1d
            - 7d
            - 30d
        timezone:
          type: string
          default: UTC
        anchor:
          type: string
          format: date-time
          description: Align the check cadence to this instant (e.g. always 9am local).
    Target:
      type: object
      required:
        - type
      description: >
        What to watch. Entity targets scrape one record per check. Search-backed
        targets re-run a query each check and diff the result set — the Sales
        Navigator "saved search / net new" pattern when paired with
        criteria.mode new_entity.
      properties:
        type:
          type: string
          enum:
            - profile
            - profile_list
            - company
            - company_jobs
            - post
            - post_search
            - people_search
            - company_search
        linkedin_url:
          type: string
          description: Required for profile, company, company_jobs, post.
        urls:
          type: array
          maxItems: 1000
          items:
            type: string
          description: For profile_list — 1 credit per URL per check.
        filters:
          type: object
          description: >
            For company_jobs / people_search / company_search — same filter
            shape as the corresponding search endpoint. Mutually exclusive with
            sales_nav_url.
        sales_nav_url:
          type: string
          description: >
            For people_search / company_search — paste a Sales Navigator search
            URL instead of structured filters (same as POST
            /v1/search/*/sales-nav). Mutually exclusive with filters.
        query:
          type: object
          description: For post_search — keywords[], hashtags[], author_url.
        max_results:
          type: integer
          default: 25
          minimum: 1
          maximum: 100
          description: >
            For search-backed targets — how many results to scrape and diff per
            check. Billed like the underlying search (2 credits per page of up
            to 25). Cap is 100 (4 pages) so checks stay bounded.
    FieldWatch:
      description: >-
        A watched field — a bare name, or an object with a numeric noise
        threshold.
      oneOf:
        - type: string
        - type: object
          required:
            - name
          properties:
            name:
              type: string
            min_change_pct:
              type: number
            min_change_abs:
              type: number
    Criteria:
      type: object
      required:
        - mode
      properties:
        mode:
          type: string
          enum:
            - field_change
            - text_match
            - new_entity
            - field_equals
            - numeric_change
            - expression
          description: >
            new_entity is the Sales Nav "net new" mode — fires when entities
            appear in a search-backed target's result set that were absent from
            the prior snapshot (identity by URN, falling back to URL).
        fields:
          type: array
          items:
            $ref: '#/components/schemas/FieldWatch'
          description: >-
            For field_change / numeric_change — fields to watch, or ["*"] for
            any non-volatile field.
        field:
          type: string
          description: For text_match / field_equals — the field to evaluate.
        contains:
          type: string
          description: text_match — normalized substring.
        any_of:
          type: array
          items:
            type: string
          description: text_match — any listed term.
        regex:
          type: string
          description: text_match — RE2 pattern.
        equals:
          type: string
          description: field_equals — fire when the field equals this value.
        expression:
          type: string
          description: expression — CEL over snapshot + diff.
        include_removals:
          type: boolean
          default: false
          description: >
            For new_entity only. When false (default), only additions fire —
            matching Sales Nav net-new alerts. When true, entities that drop out
            of the result set also produce a Trigger.
        refire:
          type: string
          enum:
            - on_change_only
            - always
          default: on_change_only
    Notify:
      type: object
      description: >-
        At least one destination; omit entirely to use the account default
        webhook.
      properties:
        webhook_url:
          type: string
        webhook_secret:
          type: string
          writeOnly: true
        emails:
          type: array
          items:
            type: string
            format: email
        slack_webhook_url:
          type: string
    SignalInput:
      type: object
      required:
        - name
        - schedule
        - target
        - criteria
      properties:
        name:
          type: string
        tags:
          type: array
          items:
            type: string
        enabled:
          type: boolean
          default: true
        schedule:
          $ref: '#/components/schemas/Schedule'
        target:
          $ref: '#/components/schemas/Target'
        criteria:
          $ref: '#/components/schemas/Criteria'
        notify:
          $ref: '#/components/schemas/Notify'
    Signal:
      allOf:
        - $ref: '#/components/schemas/SignalInput'
        - type: object
          properties:
            id:
              type: string
            status:
              type: string
              enum:
                - active
                - paused
            paused_reason:
              type:
                - string
                - 'null'
              enum:
                - insufficient_credits
                - budget_exceeded
                - webhook_failing
                - user
                - null
            estimated_monthly_credits:
              type: integer
            credits_used_this_month:
              type: integer
            last_check_at:
              type:
                - string
                - 'null'
              format: date-time
            next_check_at:
              type:
                - string
                - 'null'
              format: date-time
            last_triggered_at:
              type:
                - string
                - 'null'
              format: date-time
            created_at:
              type: string
              format: date-time
    Trigger:
      type: object
      properties:
        id:
          type: string
        signal_id:
          type: string
        check_number:
          type: integer
          description: >-
            Per-Signal monotonic counter — order deliveries by this, dedupe by
            id.
        checked_at:
          type: string
          format: date-time
        matched:
          type: boolean
        criteria_matched:
          type: array
          items:
            type: string
        diff:
          type: object
          description: >
            For field_change / numeric_change: { field: { before, after } }. For
            new_entity: { added: [...stubs], removed: [...stubs] } — removed
            only present when criteria.include_removals is true.
          additionalProperties: true
        snapshot:
          type: object
          description: >
            Full check payload. For search-backed new_entity Signals, includes
            results[] (current page set) and known_ids[] (URN/URL identity set
            used for the next diff).
        credits_used:
          type: integer
        webhook:
          type: object
          properties:
            status:
              type: string
              enum:
                - delivered
                - retrying
                - failed
            attempts:
              type: integer
            last_attempt_at:
              type: string
              format: date-time
    SignalTriggeredEvent:
      type: object
      properties:
        event:
          type: string
          const: signal.triggered
        trigger_id:
          type: string
        check_number:
          type: integer
        signal:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
            tags:
              type: array
              items:
                type: string
        target:
          $ref: '#/components/schemas/Target'
        criteria:
          $ref: '#/components/schemas/Criteria'
        diff:
          type: object
        snapshot:
          type: object
        checked_at:
          type: string
          format: date-time
    BatchItem:
      oneOf:
        - title: enrich
          type: object
          required:
            - type
            - url
          properties:
            type:
              type: string
              enum:
                - profile
                - company
                - post
            url:
              type: string
        - title: operation
          type: object
          required:
            - operation
            - body
          properties:
            operation:
              type: string
              enum:
                - search.people
                - search.companies
                - search.people.sales_nav
                - search.companies.sales_nav
                - search.jobs
                - search.posts
                - profiles.enrich
                - companies.enrich
                - posts.enrich
              description: Batchable API operation. Billed at that endpoint's normal rate.
            body:
              type: object
              description: >-
                Request body for the operation (e.g. filters + max_results for
                search).
    BatchJob:
      type: object
      properties:
        job_id:
          type: string
        status:
          type: string
          enum:
            - processing
            - completed
            - failed
        total:
          type: integer
        estimated_completion:
          type: string
          format: date-time
    BatchJobResult:
      allOf:
        - $ref: '#/components/schemas/BatchJob'
        - type: object
          properties:
            succeeded:
              type: integer
            failed:
              type: integer
            results:
              type: array
              items:
                type: object
                properties:
                  item_index:
                    type: integer
                  status:
                    type: string
                  operation:
                    type: string
                  type:
                    type: string
                    enum:
                      - profile
                      - company
                      - post
                  url:
                    type: string
                  data:
                    description: Operation result — entity record, search results, etc.
                    oneOf:
                      - $ref: '#/components/schemas/Profile'
                      - $ref: '#/components/schemas/Company'
                      - $ref: '#/components/schemas/Post'
                      - type: object
                        properties:
                          results:
                            type: array
                            items: {}
                          pagination:
                            $ref: '#/components/schemas/Pagination'
            failures:
              type: array
              items:
                type: object
                properties:
                  item_index:
                    type: integer
                  operation:
                    type: string
                  type:
                    type: string
                    enum:
                      - profile
                      - company
                      - post
                  url:
                    type: string
                  status:
                    type: string
    ProfileLookup:
      type: object
      description: Identify a profile by URL, public identifier, or LinkedIn URN.
      properties:
        url:
          type: string
          description: Profile URL or public identifier (e.g. satyanadella).
        urn:
          type: string
          description: LinkedIn member URN (e.g. ACoAAB…).
      anyOf:
        - required:
            - url
        - required:
            - urn
    CompanyLookup:
      type: object
      description: Identify a company by URL, domain, or LinkedIn company ID.
      properties:
        url:
          type: string
          description: Company page URL or slug.
        domain:
          type: string
          description: Company website domain (e.g. anthropic.com).
        linkedin_id:
          type: string
          description: Numeric LinkedIn company ID.
      anyOf:
        - required:
            - url
        - required:
            - domain
        - required:
            - linkedin_id
    CompanyStub:
      type: object
      properties:
        url:
          type: string
        name:
          type: string
        industry:
          type: string
        headcount:
          type: integer
        hq:
          type: object
          properties:
            city:
              type: string
            country:
              type: string
    FacetId:
      description: >
        LinkedIn facet id. Pass a bare string id, or `{ id, text? }` when you
        want a display label encoded into Sales Navigator URLs.
      oneOf:
        - type: string
          minLength: 1
        - type: object
          required:
            - id
          properties:
            id:
              type: string
              minLength: 1
            text:
              type: string
    PeopleSearchFilters:
      type: object
      description: >
        Structured people search constructor. Geo / industry / company / school
        take LinkedIn IDs (no typeahead). Titles and keywords are free text.
        Seniority and company size use documented enums.
      properties:
        keywords:
          type: string
        titles:
          type: array
          items:
            type: string
        past_titles:
          type: array
          items:
            type: string
        seniorities:
          type: array
          items:
            type: string
            enum:
              - owner
              - partner
              - cxo
              - vp
              - director
              - manager
              - senior
              - entry
              - training
              - strategic
        function_ids:
          type: array
          items:
            type: string
          description: LinkedIn FUNCTION ids (e.g. "25" = Sales).
        company_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
        past_company_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
        company_sizes:
          type: array
          items:
            type: string
            enum:
              - self-employed
              - 1-10
              - 11-50
              - 51-200
              - 201-500
              - 501-1000
              - 1001-5000
              - 5001-10000
              - 10001+
        industry_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
        location_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
          description: LinkedIn geo / REGION ids.
        school_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
        years_of_experience:
          type: array
          items:
            type: string
            enum:
              - '1'
              - '2'
              - '3'
              - '4'
              - '5'
        years_at_current_company:
          type: array
          items:
            type: string
            enum:
              - '1'
              - '2'
              - '3'
              - '4'
              - '5'
        years_in_current_position:
          type: array
          items:
            type: string
            enum:
              - '1'
              - '2'
              - '3'
              - '4'
              - '5'
        first_name:
          type: string
        last_name:
          type: string
        posted_on_linkedin:
          type: boolean
        recently_changed_jobs:
          type: boolean
    CompanySearchFilters:
      type: object
      description: >
        Structured company search constructor. Industry and location take
        LinkedIn IDs. Company size / type use documented enums.
      properties:
        keywords:
          type: string
        industry_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
        location_ids:
          type: array
          items:
            $ref: '#/components/schemas/FacetId'
          description: HQ geography ids.
        company_sizes:
          type: array
          items:
            type: string
            enum:
              - self-employed
              - 1-10
              - 11-50
              - 51-200
              - 201-500
              - 501-1000
              - 1001-5000
              - 5001-10000
              - 10001+
        company_types:
          type: array
          items:
            type: string
            enum:
              - public
              - educational
              - government
              - nonprofit
              - private
              - self_employed
              - self_owned
    ProfileRecommendationsList:
      type: object
      properties:
        recommendations:
          type: array
          items:
            $ref: '#/components/schemas/Recommendation'
        pagination:
          $ref: '#/components/schemas/Pagination'
    ProfileRecommendations:
      type: object
      properties:
        url:
          type: string
        urn:
          type: string
        direction:
          type: string
          enum:
            - given
            - received
            - both
          description: Echo of the requested scrape scope.
        given:
          $ref: '#/components/schemas/ProfileRecommendationsList'
        received:
          $ref: '#/components/schemas/ProfileRecommendationsList'
        scraped_at:
          type: string
          format: date-time
    Recommendation:
      type: object
      properties:
        text:
          type: string
        relationship:
          type: string
        created_at:
          type:
            - string
            - 'null'
          format: date-time
        person:
          type: object
          properties:
            url:
              type: string
            full_name:
              type: string
            headline:
              type: string
            urn:
              type: string
    CompanyInsights:
      type: object
      properties:
        url:
          type: string
        name:
          type: string
        headcount:
          type: integer
        headcount_by_function:
          type: array
          items:
            type: object
            properties:
              function:
                type: string
              count:
                type: integer
              pct:
                type: number
        headcount_by_region:
          type: array
          items:
            type: object
            properties:
              region:
                type: string
              count:
                type: integer
              pct:
                type: number
        headcount_growth:
          type: object
          properties:
            pct_6m:
              type: number
            pct_1y:
              type: number
            pct_2y:
              type: number
        hiring_trends:
          type: object
          properties:
            open_roles:
              type: integer
            top_hiring_functions:
              type: array
              items:
                type: string
        scraped_at:
          type: string
          format: date-time
    CompanyJobsCount:
      type: object
      properties:
        url:
          type: string
        open_jobs_count:
          type: integer
        scraped_at:
          type: string
          format: date-time
    CompanyHeadcountResult:
      type: object
      properties:
        company_url:
          type: string
        count:
          type: integer
        filters_applied:
          type: object
        scraped_at:
          type: string
          format: date-time
    ProfileActivityKind:
      type: string
      enum:
        - posts
        - comments
        - reactions
        - reposts
      description: One kind per request — each value is a separate scrape and billing unit.
    ProfileActivityRequest:
      allOf:
        - $ref: '#/components/schemas/ProfileLookup'
        - type: object
          required:
            - kind
          properties:
            kind:
              $ref: '#/components/schemas/ProfileActivityKind'
            posted_within:
              type: string
              enum:
                - 24h
                - week
                - month
                - all
              default: all
              description: Applies when `kind` is `posts`.
            page:
              type: integer
              default: 1
              minimum: 1
            per_page:
              type: integer
              default: 25
              minimum: 1
              maximum: 25
            pagination_token:
              type: string
              description: >-
                Required for pages after the first when returned by a prior
                response.
    ActivityTargetPost:
      type: object
      description: Post a profile commented on, reacted to, or reposted.
      properties:
        url:
          type: string
        urn:
          type: string
        text_snippet:
          type: string
        author:
          type: object
          properties:
            name:
              type: string
            url:
              type: string
    ActivityComment:
      type: object
      properties:
        text:
          type: string
        posted_at:
          type: string
          format: date-time
        target_post:
          $ref: '#/components/schemas/ActivityTargetPost'
    ActivityReaction:
      type: object
      properties:
        reaction_type:
          type: string
          enum:
            - LIKE
            - EMPATHY
            - APPRECIATION
            - INTEREST
            - PRAISE
        reacted_at:
          type:
            - string
            - 'null'
          format: date-time
        target_post:
          $ref: '#/components/schemas/ActivityTargetPost'
    ProfileActivityResult:
      type: object
      properties:
        kind:
          $ref: '#/components/schemas/ProfileActivityKind'
        url:
          type: string
        urn:
          type: string
        posts:
          type: array
          items:
            $ref: '#/components/schemas/Post'
          description: Present when `kind` is `posts`.
        comments:
          type: array
          items:
            $ref: '#/components/schemas/ActivityComment'
          description: Present when `kind` is `comments`.
        reactions:
          type: array
          items:
            $ref: '#/components/schemas/ActivityReaction'
          description: Present when `kind` is `reactions`.
        reposts:
          type: array
          items:
            $ref: '#/components/schemas/Post'
          description: Present when `kind` is `reposts`.
        pagination:
          $ref: '#/components/schemas/Pagination'
        pagination_token:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
    PostEngagementLookup:
      type: object
      description: Identify a post by URN (preferred) or URL.
      properties:
        urn:
          type: string
          description: Post activity URN (numeric). Preferred over url.
        share_urn:
          type: string
          description: Share URN when pagination requires it.
        url:
          type: string
        page:
          type: integer
          default: 1
          minimum: 1
        per_page:
          type: integer
          default: 25
          minimum: 1
          maximum: 25
      anyOf:
        - required:
            - urn
        - required:
            - url
    PostComment:
      type: object
      properties:
        text:
          type: string
        posted_at:
          type: string
          format: date-time
        replies_count:
          type: integer
        commenter:
          type: object
          properties:
            url:
              type: string
            full_name:
              type: string
            headline:
              type: string
            urn:
              type: string
    PostReaction:
      type: object
      properties:
        reaction_type:
          type: string
          enum:
            - LIKE
            - EMPATHY
            - APPRECIATION
            - INTEREST
            - PRAISE
        reacted_at:
          type:
            - string
            - 'null'
          format: date-time
        reactor:
          type: object
          properties:
            url:
              type: string
            full_name:
              type: string
            headline:
              type: string
            urn:
              type: string
    JobDetail:
      allOf:
        - $ref: '#/components/schemas/JobPosting'
        - type: object
          properties:
            job_id:
              type: string
            description:
              type: string
            employment_type:
              type: string
            experience_level:
              type: string
            salary:
              type:
                - object
                - 'null'
              properties:
                min:
                  type: integer
                max:
                  type: integer
                currency:
                  type: string
                period:
                  type: string
                  enum:
                    - hourly
                    - monthly
                    - yearly
            skills:
              type: array
              items:
                type: string
            company:
              type: object
              properties:
                name:
                  type: string
                url:
                  type: string
                headcount:
                  type: integer
                industry:
                  type: string
            scraped_at:
              type: string
              format: date-time
    Account:
      type: object
      properties:
        account_id:
          type: string
        tier:
          type: string
          enum:
            - starter
            - growth
            - scale
        credits_remaining:
          type: integer
        credits_used_this_month:
          type: integer
        price_per_1k_credits_usd:
          type: number
        rate_limit:
          type: object
          properties:
            requests_per_minute:
              type: integer
            concurrent_batch_jobs:
              type: integer
        signals:
          type: object
          properties:
            active:
              type: integer
            paused:
              type: integer
            estimated_monthly_credits:
              type: integer
        monitoring:
          type: object
          properties:
            default_webhook_url:
              type:
                - string
                - 'null'
            monthly_check_budget:
              type:
                - integer
                - 'null'
            checks_spent_this_month:
              type: integer
