# List the Companies table

The Companies table as the user sees it in mySDR: the employers of the people in the Leads table and the companies an agent saved, merged on LinkedIn page and domain. `total` is the number next to the Companies tab when no filter is set. The Leads and Companies tables are what the user sees in mySDR. Your agent decides what goes in them: search results do not land there by themselves. The user keeps the overview there; your agent reads the same tables here and fills them with POST.

## Authentication

Send `Authorization: Bearer gtk_…`. Create the key under **Connect assistant → API keys**. Every `gtk_` key can call these routes, also while the Signals API is closed. A missing, invalid or revoked key is **401**.

### Query parameters

- **`q`** `string` — Only rows whose name, title, company, place, signal or one of your own field values contains this text (up to 100 characters).
- **`source`** `string` — Only rows from the signals on Signals, or only what an agent saved. One of: `signal`, `assistant`.
- **`limit`** `integer` — How many rows to return, from 1 to 100. Defaults to 50.
- **`offset`** `integer` — Skip this many rows. Pass `next_offset` of the previous page.
- **`outreach`** `string` — Only companies whose people or general address are in this outreach state; `any` = with outreach, `none` = without. One of: `scheduled`, `ongoing`, `replied`, `done`, `any`, `none`.
- **`lifecycle`** `string` — Only rows in this state of the Status column the user sees (`lifecycle` on each row); `open` = `new`, `scheduled`, `contacted`, `replied`, `interested` and `meeting`. Several separated by commas. One of: `new`, `scheduled`, `contacted`, `replied`, `interested`, `meeting`, `later`, `no_reply`, `not_interested`, `archived`, `open`.
- **`status`** `string` — Only rows with this status; several separated by commas. A snooze that ended counts as `new`. One of: `new`, `needs_decision`, `snoozed`, `archived`.
- **`lead_status`** `string` — Only rows with this lead status; `none` = without one. Several separated by commas. One of: `interested`, `meeting`, `later`, `not_interested`, `none`.
- **`due`** `string` — By next action: `today` (today and everything overdue), `overdue`, `week` (the next 7 days and overdue), `any` (has one), `none`. One of: `today`, `overdue`, `week`, `any`, `none`.
- **`campaign`** `string` — Only rows in this campaign (a campaign id).
- **`stage`** `string` — Only rows in these stages (keys from GET /stages); `none` = without a stage. Several separated by commas.
- **`owner`** `string` — Only rows of these owners: `me`, a colleague's email address or user id (GET /team), or `none`. Several separated by commas.
- **`do_not_contact`** `boolean` — `true` = only rows on the exclusions (marked Do not contact in mySDR), `false` = only rows that may be contacted.
- **`agent_signal`** `string` — Only rows your own signals caught (POST /agent-signals/{key}/hits): their keys, separated by commas. A key the organization does not have is a 400.
- **`field.{key}`** `string` — Only rows whose own field `{key}` has this value; several separated by commas (any of them). Text without case, a number by its value, true/false or yes/no for a yes/no field. E.g. `field.ats=recruitee,teamtailor`.
- **`field.{key}.gte`** `number` — Only rows whose field `{key}` is a number of at least this. E.g. `field.fte.gte=200`.
- **`field.{key}.lte`** `number` — Only rows whose field `{key}` is a number of at most this.
- **`field.{key}.exists`** `boolean` — `true` = the field has a value, `false` = it has none. Up to 10 field filters, all must match.

## Response

- **`object`** `string` · **required** — Always `list`. One of: `list`.
- **`total`** `integer` · **required** — Rows that match this request. Without a filter: the number next to the Companies tab.
- **`data`** `object[]` · **required** — Rows, most recent activity first. `id` (the saved row that PATCH takes, or null when the company is there only through its leads), `name`, `linkedin_url`, `domain`, `industry`, `country_code`, `employees`, `leads` (how many of its people are in the Leads table), `people` (up to five, with `name` and `title`), `signals`, `agent_signals` (your own signals that caught it, newest first: `key`, `name`, `first_at`, `last_at`, `summary` (what you last saw) and `source_url`; empty = none) (on the company or one of its people), `technologies`, `funding` (`round`, `amount`, `currency`, `date`, or null), `sources`, `saved_ids` (what DELETE takes; empty when the company is there only through its leads), `last_seen_at`, `lifecycle` (the Status column: the state of its most advanced lead, or `archived`/`later` when the company itself is archived or snoozed; read-only), the state (`status`, `status_reason`, `snooze_until`, `lead_status`, `next_action` (`at`, `kind`, `note`, `email` when you planned one, without its `text` in a list, or null), `out_of_office_until`, `fields`, `campaign_ids`, `stage` (a stage key, or null) and `owner` (`id`, `name`, `email`, or null), plus `contact_points`), `outreach` (its people and general address together) and `do_not_contact` (the exclusions on its domain or name, each with `type`, `reason` and `message`; empty = may be contacted).
- **`next_offset`** `integer | null` · **required** — The offset of the next page, or null.
- **`table`** `object` · **required** — `companies`, `with_leads`, `saved_by_assistant`, `lifecycle` (a count per state of the Status column), `status` (a count per status), `outreach` (a count per state, or null), `due_today`, `do_not_contact` and `capped`.
- **`dashboard_url`** `string` · **required** — The Companies table in mySDR.

## Credits

Free. This call never uses credits.

## Errors

- **400** `invalid_request` — An unknown `source`, `outreach`, `lifecycle`, `status`, `lead_status` or `due`, a `campaign` that is not an id, a `stage` that is not a key, an `owner` who is not in the organization, an `agent_signal` the organization does not have, a field filter that is not valid (`param` names it), a `do_not_contact` that is not true or false, a `limit` outside 1 to 100, or a negative `offset`.
- **401** `authentication_error` — The Authorization header is missing, or the key is unknown or revoked.
- **403** `permission_error` — API access is not part of your plan, or your account is suspended.
- **429** `rate_limit_error` — More than 60 requests per minute, or more than 3 at the same time, on one key. Wait for the Retry-After header.
- **503** `service_unavailable` — The API is temporarily unavailable. Retry later.
- **500** `internal_error` — Something went wrong on our side.

## Example

### cURL

```bash
curl "https://mysdr.app/api/v1/tables/companies?limit=25" \
  -H "Authorization: Bearer $MYSDR_API_KEY"
```

### JavaScript

```javascript
const response = await fetch('https://mysdr.app/api/v1/tables/companies?limit=25', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.MYSDR_API_KEY}`
  }
});
const body = await response.json();
```

### Python

```python
import json
import os
import urllib.request

request = urllib.request.Request(
    "https://mysdr.app/api/v1/tables/companies?limit=25",
    headers={
    "Authorization": f"Bearer {os.environ['MYSDR_API_KEY']}"
    },
    method="GET",
)
with urllib.request.urlopen(request) as response:
    body = json.load(response)
```

### Example response

```json
{
  "object": "list",
  "total": 1,
  "data": [
    {
      "object": "table_company",
      "name": "Acme Analytics",
      "linkedin_url": "https://www.linkedin.com/company/acme-analytics",
      "domain": "acme.io",
      "industry": "Software Development",
      "country_code": "BE",
      "employees": 85,
      "leads": 2,
      "people": [
        {
          "name": "Jane Example",
          "title": "CFO"
        }
      ],
      "signals": [
        "Companies that raised funding · BE"
      ],
      "technologies": [],
      "funding": {
        "round": "Series A",
        "amount": 12000000,
        "currency": "EUR",
        "date": "2026-10-14"
      },
      "sources": [
        "signal",
        "assistant"
      ],
      "saved_ids": [
        "cmp_01J9Z6P8C8V0K3W6T2N8R5M1XC"
      ],
      "last_seen_at": "2026-10-23T09:30:00.000Z",
      "lifecycle": "contacted"
    }
  ],
  "next_offset": null,
  "table": {
    "companies": 1,
    "with_leads": 1,
    "saved_by_assistant": 1,
    "capped": false
  },
  "dashboard_url": "https://mysdr.app/en/gtm/companies"
}
```
