> ## 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.

# Export signals to CSV API

> Download an adoption or churn query as a 27-column CSV with company and contact data attached. Billed at 1 credit per exported row, charged after completion.

## Frequently asked questions

<AccordionGroup>
  <Accordion title="How is the export billed?">
    One credit per exported row, charged after the export completes. The `X-Credits-Cost` and `X-Export-Rows` response headers report the exact figures. Because the underlying scan runs regardless of how many rows you take, every export that runs debits at least 1 credit — a key can never trigger more scans than it holds credits.
  </Accordion>

  <Accordion title="What happens if the match is bigger than my credit balance?">
    The export is capped to your remaining credits. You receive the most recent N rows, you are charged N, and the response carries `X-Export-Capped: credits`. Top up and run it again to pull the rest. A key with zero credits gets a 402 and the scan never runs at all.
  </Accordion>

  <Accordion title="How do I limit what I download and pay for?">
    Pass `limit`. It bounds both the delivered rows and the bill, and is clamped to 10,000. Omit it for a full export up to that cap. For extraction beyond 10,000 rows, use [lead lists](/docs/api-reference/lead-lists/create-lead-list-api) instead — they run as a background job built for volume.
  </Accordion>

  <Accordion title="Which columns are in the file?">
    Always the same 27, in the same order, regardless of which filters produced the export: 10 signal columns, 9 LinkedIn company columns, and 8 website columns from the crawl (emails, phones, five social profile URLs, and site language). The company and website blocks ride every export, so a query filtered on `has_email=true` actually returns the email addresses. Both blocks are left-joined, so a domain with no match exports empty cells rather than being dropped.
  </Accordion>

  <Accordion title="Can I export switch or whitespace results?">
    Not yet. Export covers `churn` and `adoption` only, because switch and whitespace have different row shapes. For those, page through the JSON endpoints or build a [lead list](/docs/api-reference/lead-lists/create-lead-list-api).
  </Accordion>
</AccordionGroup>


## OpenAPI

````yaml GET /v1/signals/{type}/export
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/signals/{type}/export:
    get:
      tags:
        - Signals
      summary: Export signals to CSV API
      description: >-
        Download an adoption or churn query as a CSV file. Takes the same scope,
        window and filters as the JSON endpoint — forward the identical query
        parameters.


        **Billing is 1 credit per exported row, charged after completion.**
        `X-Credits-Cost` and `X-Export-Rows` report the exact figures. If the
        match is larger than your balance the export is capped to your remaining
        credits and the response carries `X-Export-Capped: credits`. Because the
        underlying scan runs regardless of `LIMIT`, every export that runs
        debits at least 1 credit.


        Every export carries the same fixed 27 columns regardless of which
        filters produced it: 10 signal columns, 9 LinkedIn company columns and 8
        website columns from the crawl.
      operationId: exportSignals
      parameters:
        - name: type
          in: path
          required: true
          description: >-
            The signal type to export. Switch and whitespace have different row
            shapes and are not exportable.
          schema:
            type: string
            enum:
              - churn
              - adoption
            example: adoption
        - name: technology_id
          in: query
          required: false
          description: >-
            Scope by BuiltWith technology id. Provide exactly one of
            `technology_id`, `technology` or `category_id`.
          schema:
            type: integer
          example: 2184
        - name: technology
          in: query
          required: false
          description: Scope by exact technology name. The technology must be detectable.
          schema:
            type: string
          example: Shopify
        - name: category_id
          in: query
          required: false
          description: >-
            Scope by category — fans out to every detectable technology whose
            *primary* category is this one.
          schema:
            type: integer
          example: 202
        - name: window
          in: query
          required: false
          description: Look-back window in days. Clamped to 1–365.
          schema:
            type: string
            default: '30'
        - name: limit
          in: query
          required: false
          description: >-
            Bounds both the delivered rows and the bill. Clamped to 10,000. Omit
            for a full export up to that cap.
          schema:
            type: integer
            maximum: 10000
          example: 1000
        - name: min_confidence
          in: query
          required: false
          description: Minimum `detection_rate` for a row to be exported.
          schema:
            type: number
            format: float
            default: 0.5
        - name: include_first_seen
          in: query
          required: false
          description: Adoption only. Disables the first-seen gate.
          schema:
            type: boolean
            default: false
        - $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/FirmoCompany'
        - $ref: '#/components/parameters/WebHasEmail'
        - $ref: '#/components/parameters/WebHasPhone'
        - $ref: '#/components/parameters/WebSocial'
        - $ref: '#/components/parameters/WebLanguage'
        - $ref: '#/components/parameters/WebCountry'
        - $ref: '#/components/parameters/SegmentId'
      responses:
        '200':
          description: CSV file with a fixed 27-column header
          headers:
            X-Credits-Cost:
              description: Credits charged for this export (one per exported row).
              schema:
                type: integer
            X-Export-Rows:
              description: Number of rows in the file.
              schema:
                type: integer
            X-Export-Capped:
              description: >-
                Present as `credits` when the export was truncated to your
                remaining balance.
              schema:
                type: string
            Content-Disposition:
              description: '`attachment` with a generated filename.'
              schema:
                type: string
          content:
            text/csv:
              schema:
                type: string
                format: binary
              example: >-
                domain,subdomain,technology_id,technology_name,event_at,last_detected,detection_rate,detection_count,confidence_score,confidence_label,company_name,company_industry,company_employees,company_country,company_city,company_state,company_founded,company_type,linkedin_url,emails,phones,social_linkedin,social_x,social_facebook,social_instagram,social_youtube,web_language

                example.com,WWW.EXAMPLE.COM,2184,Shopify,2026-05-31
                14:10:33,2026-04-18 07:39:59,0.86,6,79,high,Example
                Inc.,Retail,51-200,united states,austin,texas,2015,Privately
                Held,linkedin.com/company/example,hi@example.com,+1 555
                0100,https://www.linkedin.com/company/example,,,,,en
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
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
    FirmoCompany:
      name: company
      in: query
      required: false
      description: >-
        Set to `true` to attach the company card without filtering results
        (enrich-only mode).
      schema:
        type: boolean
      example: true
    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
    SegmentId:
      name: segment_id
      in: query
      required: false
      description: >-
        Apply a saved audience instead of inline filters. Filter audiences
        replay their firmographic predicates; list audiences restrict rows to
        their member domains. Mutually exclusive with inline firmographic
        parameters.
      schema:
        type: string
      example: seg_8f3a2c1b
  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
    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'
  schemas:
    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
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key in format `tapi_live_[32-char]` (live) or `tapi_test_[32-char]`
        (test)

````