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

# List Companies

> Companies Huntd tracks for your organization, paginated and date-filterable

<Note>
  **Availability:** Enterprise plan, on `https://app.gethuntd.com`. Agency keys receive
  `403 ENDPOINT_NOT_ON_PLAN`. Uses no credits.
</Note>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://app.gethuntd.com/api/v1/public/companies?limit=50" \
    -H "X-API-Key: hntd_abc12345_yoursecretkey"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({ limit: '50' });

  const response = await fetch(
    `https://app.gethuntd.com/api/v1/public/companies?${params}`,
    { headers: { 'X-API-Key': process.env.HUNTD_API_KEY } }
  );

  const { data, pagination } = await response.json();
  console.log(`${data.length} of ${pagination.total} companies`);
  ```

  ```python Python theme={null}
  import requests
  import os

  response = requests.get(
      'https://app.gethuntd.com/api/v1/public/companies',
      params={'limit': 50},
      headers={'X-API-Key': os.environ['HUNTD_API_KEY']}
  )

  body = response.json()
  print(f"{len(body['data'])} of {body['pagination']['total']} companies")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "pagination": { "page": 1, "limit": 50, "total": 3866, "totalPages": 78 },
    "data": [
      {
        "domain": "acme.com",
        "name": "Acme",
        "size": 2100,
        "industry": "banking,financial services",
        "country": "United States",
        "people": 12,
        "sources": ["devin", "factory"],
        "discoveredAt": "2026-07-31T18:31:58.294Z"
      }
    ]
  }
  ```

  ```json 400 theme={null}
  {
    "success": false,
    "error": {
      "code": "INVALID_PARAMETER",
      "message": "`limit` may not exceed 1000."
    }
  }
  ```

  ```json 401 theme={null}
  {
    "success": false,
    "error": {
      "code": "INVALID_API_KEY",
      "message": "API key is missing, invalid, or has been revoked."
    }
  }
  ```

  ```json 403 theme={null}
  {
    "success": false,
    "error": {
      "code": "SOURCE_NOT_ALLOWED",
      "message": "Your organization does not have access to source `gong`."
    }
  }
  ```
</ResponseExample>

## Overview

Returns the companies (accounts) Huntd tracks for your organization, newest first. Supports
[pagination](/public-api/conventions#pagination),
[date filtering](/public-api/conventions#date-filtering) and
[`source` / `is_user` filtering](/public-api/conventions#filtering).

<Warning>
  An empty `sources` array means **we checked and found no user**, not that the company is
  untracked.
</Warning>

## Joining to People

`companyDomain` on [List People](/public-api/people) is normalized to exactly match `domain` here,
so the two endpoints join directly with no cleanup.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const key = { 'X-API-Key': process.env.HUNTD_API_KEY };
  const base = 'https://app.gethuntd.com/api/v1/public';

  const companies = await (await fetch(`${base}/companies?limit=1000`, { headers: key })).json();
  const people = await (await fetch(`${base}/people?limit=1000&is_user=true`, { headers: key })).json();

  // Group people under their company by domain
  const byDomain = new Map(companies.data.map((c) => [c.domain, { ...c, people: [] }]));
  for (const person of people.data) {
    byDomain.get(person.companyDomain)?.people.push(person);
  }
  ```

  ```python Python theme={null}
  import os
  import requests

  key = {'X-API-Key': os.environ['HUNTD_API_KEY']}
  base = 'https://app.gethuntd.com/api/v1/public'

  companies = requests.get(f'{base}/companies', params={'limit': 1000}, headers=key).json()
  people = requests.get(f'{base}/people', params={'limit': 1000, 'is_user': 'true'}, headers=key).json()

  # Group people under their company by domain
  by_domain = {c['domain']: {**c, 'people': []} for c in companies['data']}
  for person in people['data']:
      company = by_domain.get(person['companyDomain'])
      if company:
          company['people'].append(person)
  ```
</CodeGroup>

<Note>
  The `people` **integer** on this endpoint is the count Huntd tracks. It won't always equal the
  number of rows List People returns for that domain, because your people query may be filtered by
  source, date or `is_user`.
</Note>

For a full export, use [Stream Companies](/public-api/companies-stream).

## Errors

| HTTP | Error Code | Description |
| - | - | - |
| 400 | `INVALID_PARAMETER` | A query parameter is malformed or out of range |
| 401 | `INVALID_API_KEY` | API key is missing, invalid, or has been revoked |
| 403 | `ENDPOINT_NOT_ON_PLAN` | Your plan doesn't include this endpoint (Agency keys) |
| 403 | `SUBSCRIPTION_INACTIVE` | Your workspace has no active subscription. Contact your account manager. |
| 403 | `SOURCE_NOT_ALLOWED` | Your organization doesn't have access to the requested `source` |
| 423 | `SOURCE_UNAVAILABLE` | The requested `source` is paused for maintenance. Retry later. |
| 429 | `RATE_LIMIT_EXCEEDED` | Over 60 requests per minute. Wait `Retry-After` seconds. |
| 500 | `INTERNAL_ERROR` | Something broke on our side. Safe to retry. |
| 503 | `ORG_KIND_UNAVAILABLE` | Your plan briefly couldn't be confirmed. Retry. |


## OpenAPI

````yaml api-reference/public-api.json GET /api/v1/public/companies
openapi: 3.0.3
info:
  title: Huntd Public API
  version: 1.0.0
  description: >-
    Read what Huntd tracks for your organization (enterprise plan), or check one
    email address against the products you track (Agency plan).
  contact:
    name: Huntd Support
    email: support@gethuntd.com
servers:
  - url: https://app.gethuntd.com
    description: Public API
security:
  - ApiKeyAuth: []
tags:
  - name: Public API
  - name: Email Check
paths:
  /api/v1/public/companies:
    get:
      tags:
        - Public API
      summary: List Companies
      description: >-
        Companies Huntd tracks for your organization, paginated and
        date-filterable.
      operationId: listCompanies
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/skip_count'
        - $ref: '#/components/parameters/discovered_days'
        - $ref: '#/components/parameters/discovered_from'
        - $ref: '#/components/parameters/discovered_to'
        - $ref: '#/components/parameters/source'
        - $ref: '#/components/parameters/is_user'
      responses:
        '200':
          description: A page of companies
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompaniesPage'
              example:
                success: true
                pagination:
                  page: 1
                  limit: 50
                  total: 3866
                  totalPages: 78
                data:
                  - domain: acme.com
                    name: Acme
                    size: 2100
                    industry: banking,financial services
                    country: United States
                    people: 12
                    sources:
                      - devin
                      - factory
                    discoveredAt: '2026-07-31T18:31:58.294Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ForbiddenRows'
        '423':
          $ref: '#/components/responses/SourceUnavailable'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/PlanUnavailable'
components:
  parameters:
    page:
      name: page
      in: query
      required: false
      description: 1-indexed page number.
      schema:
        type: integer
        minimum: 1
        default: 1
    limit:
      name: limit
      in: query
      required: false
      description: >-
        Results per page. Maximum 1000: a higher value returns `400
        INVALID_PARAMETER` rather than being clamped.
      schema:
        type: integer
        minimum: 1
        maximum: 1000
        default: 100
    skip_count:
      name: skip_count
      in: query
      required: false
      description: >-
        Skip the count query. `total` and `totalPages` come back `null`, which
        is faster on large result sets.
      schema:
        type: string
        enum:
          - '1'
          - 'true'
    discovered_days:
      name: discovered_days
      in: query
      required: false
      description: >-
        The last N UTC days, including today (`2` = today and yesterday).
        "Discovered" means when we last checked the row, not when it was
        confirmed. Can't be combined with `discovered_from` / `discovered_to`.
      schema:
        type: integer
        minimum: 1
        maximum: 366
    discovered_from:
      name: discovered_from
      in: query
      required: false
      description: Inclusive UTC start day, `YYYY-MM-DD`.
      schema:
        type: string
        format: date
        example: '2026-07-01'
    discovered_to:
      name: discovered_to
      in: query
      required: false
      description: Inclusive UTC end day, `YYYY-MM-DD`.
      schema:
        type: string
        format: date
        example: '2026-07-31'
    source:
      name: source
      in: query
      required: false
      description: Restrict to one source slug, as returned by List Sources.
      schema:
        type: string
        example: gong
    is_user:
      name: is_user
      in: query
      required: false
      description: >-
        `true`: confirmed users only. `false`: checked but not a user. `all`:
        both.
      schema:
        type: string
        enum:
          - all
          - 'true'
          - 'false'
        default: all
  schemas:
    CompaniesPage:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
        pagination:
          $ref: '#/components/schemas/Pagination'
        data:
          type: array
          items:
            $ref: '#/components/schemas/Company'
    Pagination:
      type: object
      properties:
        page:
          type: integer
          example: 1
        limit:
          type: integer
          example: 100
        total:
          type: integer
          nullable: true
          description: '`null` when `skip_count` is set.'
          example: 842
        totalPages:
          type: integer
          nullable: true
          description: '`null` when `skip_count` is set.'
          example: 9
    Company:
      type: object
      description: A company (account) Huntd tracks for your organization
      properties:
        domain:
          type: string
          description: >-
            Normalized domain. The stable key: deduplicate and join to
            `companyDomain` on List People with it.
        name:
          type: string
          nullable: true
          description: Company display name.
        size:
          type: integer
          nullable: true
          description: Employee count.
        industry:
          type: string
          nullable: true
          description: Comma-separated industry labels.
        country:
          type: string
          nullable: true
          description: Country.
        people:
          type: integer
          description: How many tracked people you have at this company.
        sources:
          type: array
          items:
            type: string
          description: >-
            Source slugs with at least one confirmed user at this company. Empty
            means we checked and found no user.
        discoveredAt:
          type: string
          format: date-time
          nullable: true
          description: When we last checked this company (UTC).
      example:
        domain: acme.com
        name: Acme
        size: 2100
        industry: banking,financial services
        country: United States
        people: 12
        sources:
          - devin
          - factory
        discoveredAt: '2026-07-31T18:31:58.294Z'
    ApiError:
      type: object
      description: Every error uses this envelope. Branch on `error.code`, not the message.
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INVALID_PARAMETER
                - INVALID_BODY
                - INVALID_API_KEY
                - ENDPOINT_NOT_ON_PLAN
                - SOURCE_NOT_ALLOWED
                - SUBSCRIPTION_INACTIVE
                - JOB_NOT_FOUND
                - SOURCE_NOT_VERIFIABLE
                - SOURCE_UNAVAILABLE
                - RATE_LIMITED
                - RATE_LIMIT_EXCEEDED
                - QUOTA_EXCEEDED
                - STREAM_FAILED
                - INTERNAL_ERROR
                - ORG_KIND_UNAVAILABLE
            message:
              type: string
              description: Human-readable. May change.
  responses:
    BadRequest:
      description: A query parameter is malformed or out of range
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          examples:
            limit:
              summary: limit over 1000
              value:
                success: false
                error:
                  code: INVALID_PARAMETER
                  message: '`limit` may not exceed 1000.'
            dates:
              summary: Both date styles given
              value:
                success: false
                error:
                  code: INVALID_PARAMETER
                  message: >-
                    Use either `discovered_days` or
                    `discovered_from`/`discovered_to`, not both.
    Unauthorized:
      description: API key is missing, malformed, unknown or revoked
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: INVALID_API_KEY
              message: API key is missing, invalid, or has been revoked.
    ForbiddenRows:
      description: >-
        Not available on your plan, or no access to the requested source, or no
        active subscription
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          examples:
            notOnPlan:
              summary: Agency key calling an enterprise endpoint
              value:
                success: false
                error:
                  code: ENDPOINT_NOT_ON_PLAN
                  message: >-
                    This endpoint is not available on your plan. Use POST
                    /verify to check an address.
            sourceNotAllowed:
              summary: No access to the requested source
              value:
                success: false
                error:
                  code: SOURCE_NOT_ALLOWED
                  message: Your organization does not have access to source `gong`.
            subscriptionInactive:
              summary: Workspace has no active subscription
              value:
                success: false
                error:
                  code: SUBSCRIPTION_INACTIVE
                  message: >-
                    This workspace doesn't have an active subscription. Please
                    contact your account manager to restore access.
    SourceUnavailable:
      description: The requested source is paused for maintenance
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: SOURCE_UNAVAILABLE
              message: Source `gong` is temporarily unavailable for maintenance.
    RateLimited:
      description: Over the API key's per-minute limit
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: RATE_LIMIT_EXCEEDED
              message: Rate limit exceeded — 60 requests per minute. Retry in 23s.
      headers:
        Retry-After:
          description: Seconds to wait before the next request.
          schema:
            type: integer
    InternalError:
      description: Internal error. Safe to retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: INTERNAL_ERROR
              message: Internal server error.
    PlanUnavailable:
      description: Your plan briefly could not be confirmed. Retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            success: false
            error:
              code: ORG_KIND_UNAVAILABLE
              message: >-
                Your organization's plan could not be checked. Please retry in a
                moment.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        API key in format: hntd_{id}_{secret}. Create one in Settings → API &
        webhooks. `Authorization: Bearer` is also accepted.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.