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

# Audience technology report API

> What a group of companies actually runs — per-technology domain counts, penetration and a data freshness block. Costs 1 credit.

## Frequently asked questions

<AccordionGroup>
  <Accordion title="What is penetration?">
    The share of the audience's *in-corpus* members running that technology. The denominator is `coverage.in_corpus` — members we hold detection data for — not the raw member count. That matters: if you upload 5,914 domains and we have data on 5,114, penetration is out of 5,114, and the response says so.
  </Accordion>

  <Accordion title="What is the freshness block for?">
    Under a rolling crawl, "how current is this data" is a distribution rather than a yes or no. The block gives you the median last-scan age and the share of members scanned within 7 and 30 days, so you can judge how much to trust the numbers — and decide whether to buy a [refresh crawl](/docs/api-reference/audiences/refresh-audience-crawl-api).
  </Accordion>

  <Accordion title="Can I profile just part of the group?">
    Yes. Add inline firmographic parameters and the membership is intersected with matching companies *before* the rollup, so coverage, penetration and freshness all describe the slice. "What does the US half of my customer base run?" is one request.
  </Accordion>

  <Accordion title="Why is the query timing out?">
    A 503 with `SEGMENT_QUERY_TIMEOUT` means the query hit the 30-second server-side limit. It is never retried automatically, because the killed query already consumed its full budget. Narrow the audience or add a firmographic slice and try again.
  </Accordion>

  <Accordion title="Why not just sum these numbers per category myself?">
    Because a domain running two tools in the same category would be counted twice. Use [the breakdown endpoint](/docs/api-reference/audiences/audience-breakdown-api) with `by=category`, which does server-side distinct-domain counting.
  </Accordion>
</AccordionGroup>


## OpenAPI

````yaml GET /v1/segments/{id}/technologies
openapi: 3.1.0
info:
  title: TechnologyChecker API
  description: >-
    Discover technology stacks, track market trends, and enrich data with
    company intelligence.
  version: 1.0.0
  contact:
    name: TechnologyChecker Support
    email: support@technologychecker.io
    url: https://technologychecker.io
servers:
  - url: https://api.technologychecker.io
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Domain technologies
    description: Look up technologies detected on any domain
  - name: Technology data
    description: Search, look up, and get details on tracked technologies
  - name: Market intelligence
    description: Technology stats, trends, and market share
  - name: Company data
    description: Firmographic and company intelligence
  - name: Live detection
    description: Real-time technology detection with browser rendering
  - name: Signals
    description: >-
      Intent signals derived from technology state transitions: who adopted, who
      churned, who switched, and who has a gap in their stack.
  - name: Alerts
    description: >-
      Saved signal queries delivered to your webhook. Every signal you can
      query, you can subscribe to.
  - name: Audiences
    description: >-
      Saved groups of domains — uploaded lists or computed recipes — that you
      can profile, slice and monitor.
  - name: Lead lists
    description: >-
      Build and export targeted domain lists combining technology detection with
      company data.
paths:
  /v1/segments/{id}/technologies:
    get:
      tags:
        - Audiences
      summary: Audience technology report API
      description: >-
        What does this group of companies actually run? Per-technology active
        domain counts across the audience's membership, with penetration as a
        share of the members we hold data for.


        The response includes a `freshness` block — median last-scan age and the
        share of members scanned within 7 and 30 days. Under a rolling crawl,
        "how current is this data" is a distribution rather than a yes or no,
        and this is the honest answer.


        Add inline firmographic parameters to slice the group before the rollup,
        so coverage, penetration and freshness all describe the slice (for
        example your portfolio list intersected with US companies) rather than
        the whole list.


        Costs 1 credit.
      operationId: getAudienceTechnologies
      parameters:
        - name: id
          in: path
          required: true
          description: The audience id.
          schema:
            type: string
            example: seg_8f3a2c1b
        - $ref: '#/components/parameters/FirmoCountry'
        - $ref: '#/components/parameters/FirmoCity'
        - $ref: '#/components/parameters/FirmoState'
        - $ref: '#/components/parameters/FirmoIndustry'
        - $ref: '#/components/parameters/FirmoIndustryCode'
        - $ref: '#/components/parameters/FirmoEmployees'
        - $ref: '#/components/parameters/FirmoCompanyType'
        - $ref: '#/components/parameters/FirmoFoundedMin'
        - $ref: '#/components/parameters/FirmoFoundedMax'
        - $ref: '#/components/parameters/WebHasEmail'
        - $ref: '#/components/parameters/WebHasPhone'
        - $ref: '#/components/parameters/WebSocial'
        - $ref: '#/components/parameters/WebLanguage'
        - $ref: '#/components/parameters/WebCountry'
      responses:
        '200':
          description: Per-technology counts, penetration and data freshness
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      segment:
                        type: object
                        properties:
                          id:
                            type: string
                            example: seg_8f3a2c1b
                          name:
                            type: string
                            example: YC W25 portfolio
                          type:
                            type: string
                            example: list
                          kind:
                            type: string
                            example: upload
                          domain_count:
                            type: integer
                            example: 5914
                      coverage:
                        type: object
                        properties:
                          in_corpus:
                            type: integer
                            description: >-
                              Members we hold detection data for. This is the
                              denominator for penetration and freshness.
                            example: 5114
                          total:
                            type: integer
                            example: 5914
                          note:
                            type: string
                      firmographics:
                        $ref: '#/components/schemas/FirmographicsEcho'
                      freshness:
                        type: object
                        properties:
                          median_age_days:
                            type: integer
                            nullable: true
                            example: 12
                          scanned_7d_pct:
                            type: number
                            format: float
                            nullable: true
                            example: 31.4
                          scanned_30d_pct:
                            type: number
                            format: float
                            nullable: true
                            example: 88.2
                      technologies:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              example: 2
                            name:
                              type: string
                              example: Cloudflare
                            category:
                              type: string
                              nullable: true
                              example: CDN
                            domains:
                              type: integer
                              example: 1785
                            penetration:
                              type: number
                              format: float
                              nullable: true
                              description: >-
                                Share of in-corpus members running this
                                technology.
                              example: 0.663
                      count:
                        type: integer
                        example: 250
                      generated_at:
                        type: string
                        example: '2026-07-29T10:20:11.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/QueryTimeout'
components:
  parameters:
    FirmoCountry:
      name: country
      in: query
      required: false
      description: Filter to companies in this country (case-insensitive).
      schema:
        type: string
      example: united states
    FirmoCity:
      name: city
      in: query
      required: false
      description: Filter to companies in this city (case-insensitive).
      schema:
        type: string
    FirmoState:
      name: state
      in: query
      required: false
      description: Filter to companies in this state or region (case-insensitive).
      schema:
        type: string
    FirmoIndustry:
      name: industry
      in: query
      required: false
      description: Filter to companies in this industry (case-insensitive).
      schema:
        type: string
      example: retail
    FirmoIndustryCode:
      name: industry_code
      in: query
      required: false
      description: Filter by exact LinkedIn industry code.
      schema:
        type: integer
    FirmoEmployees:
      name: employees
      in: query
      required: false
      description: >-
        Filter by exact LinkedIn employee band. Unknown bands are rejected with
        `INVALID_EMPLOYEE_BAND` and the allowed list.
      schema:
        type: string
      example: 51-200
    FirmoCompanyType:
      name: company_type
      in: query
      required: false
      description: Filter by exact company type.
      schema:
        type: string
      example: Privately Held
    FirmoFoundedMin:
      name: founded_min
      in: query
      required: false
      description: Only companies founded in or after this year.
      schema:
        type: integer
        minimum: 1800
        maximum: 2025
    FirmoFoundedMax:
      name: founded_max
      in: query
      required: false
      description: Only companies founded in or before this year.
      schema:
        type: integer
        minimum: 1800
        maximum: 2025
    WebHasEmail:
      name: has_email
      in: query
      required: false
      description: >-
        Filter to domains where the crawler found (or did not find) an email
        address. `false` is a real filter, not a no-op.
      schema:
        type: boolean
    WebHasPhone:
      name: has_phone
      in: query
      required: false
      description: >-
        Filter to domains where the crawler found (or did not find) a phone
        number.
      schema:
        type: boolean
    WebSocial:
      name: social
      in: query
      required: false
      description: Filter to domains publishing a profile on this platform.
      schema:
        type: string
        enum:
          - linkedin
          - x
          - facebook
          - instagram
          - youtube
          - github
          - tiktok
          - discord
          - reddit
          - crunchbase
          - slack
      example: instagram
    WebLanguage:
      name: language
      in: query
      required: false
      description: Filter by the site's primary language.
      schema:
        type: string
      example: de
    WebCountry:
      name: web_country
      in: query
      required: false
      description: >-
        Filter by the country the site declares in its schema.org markup.
        Accepts ISO-2, English name or common variants.
      schema:
        type: string
      example: USA
  schemas:
    FirmographicsEcho:
      type: object
      description: Echo of the firmographic predicates that took effect on this request.
      properties:
        applied:
          type: object
          additionalProperties: true
          example:
            country: united states
            employees: 51-200
        filtered:
          type: boolean
          description: >-
            `true` when results were narrowed to matched companies; `false` for
            enrich-only (`company=true`).
          example: true
        note:
          type: string
          example: >-
            Results are limited to domains with a matched LinkedIn company that
            passes these filters (~23–30% of tech-domains have a company match).
    ApiError:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              example: UNAUTHORIZED
            message:
              type: string
              example: Missing or invalid API key
  responses:
    BadRequest:
      description: Invalid or missing parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: VALIDATION_ERROR
              message: >-
                Provide exactly one scope: technology_id, technology or
                category_id.
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    PaymentRequired:
      description: Not enough credits, or the plan does not include this feature
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: INSUFFICIENT_CREDITS
              message: Insufficient credits for this request.
              details:
                required: 1
                available: 0
    Forbidden:
      description: The plan does not allow this action, or a plan limit was reached
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: PLAN_LIMIT
              message: >-
                Your plan allows up to 2 saved audiences. Delete one to create
                another.
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    RateLimited:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    QueryTimeout:
      description: >-
        The query exceeded the 30-second server-side limit. Narrow the query and
        retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: SEGMENT_QUERY_TIMEOUT
              message: The segment query exceeded the 30s server-side limit.
              details:
                suggestion: >-
                  Narrow the segment — add an employees band, industry, or city
                  — and try again.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key in format `tapi_live_[32-char]` (live) or `tapi_test_[32-char]`
        (test)

````