# Look up a company

> POST /v1/companies/lookup. Companies House fields for one company, by number, domain or name, and for signed-in callers the contacts we hold there by job level (a single company count needs an account and is logged; signed out, the counts are null).

Source: https://emailmovers.com/mydatahub/docs/reference/rest/lookup-company

`POST /v1/companies/lookup`

Companies House fields for one company, by number, domain or name, and for signed-in callers the contacts we hold there by job level (a single company count needs an account and is logged; signed out, the counts are null). No contact details, and no charge (to confirm).

| Property | Value |
| --- | --- |
| Endpoint | `POST https://mydatahub.emailmovers.com/v1/companies/lookup` |
| Operation id | `lookupCompany` |
| Cost | Free (0 credits) |
| Access | No account needed. An API key or OAuth token with the scope `counts:read` is optional and adds your organisation's own figures. |
| MCP tool | [`lookup_company`](https://emailmovers.com/mydatahub/docs/reference/mcp/lookup_company.md) |
| Tag | Lookups |

> **Not yet live.** MyDataHub v2 is built and tested locally and is not yet live. The v2 hosts open at launch, date to confirm. This page describes the contract the API is tested against.

## Request

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `MyDataHub-Version` | header | string | no | The dated API version, pinned per key when left out. Non-breaking changes ship as new dates; the path major changes only for breaking changes, with a 12 month deprecation window. |

### Body

| Member | Type | Required | Description |
| --- | --- | --- | --- |
| `company_number` | string | no | Eight characters in upper case, such as 05046417 or SC123456. |
| `domain` | string | no |  |
| `name` | string | no |  |
| `town` | string | no | Narrows a name search. |

## Example request

```bash
curl -X POST "https://mydatahub.emailmovers.com/v1/companies/lookup" \
  -H "Content-Type: application/json" \
  --data '{
  "company_number": "12345678"
}'
```

## Responses

### 200: The company.

Headers: `RateLimit`, `RateLimit-Policy`.

| Member | Type | Always present | Description |
| --- | --- | --- | --- |
| `match_confidence` | number (0 to 1) | yes |  |
| `dataset_version` | string | yes | The immutable weekly build a count is bound to, such as 2026-W39. The last 52 stay queryable. |
| `company` | object | yes |  |
| `company.companies_house_number` | string or null | yes |  |
| `company.name` | string | yes |  |
| `company.status` | string | yes |  |
| `company.type` | string | yes |  |
| `company.subscriber_class` | enum: `ltd`, `plc`, `llp`, `scottish_partnership`, `public_body`, `charity_incorporated`, `sole_trader`, `ordinary_partnership`, and 1 more | yes |  |
| `company.incorporation_date` | string (date) or null | yes |  |
| `company.sic_2007` | array of `SicCode` | yes |  |
| `company.employee_band` | string or null | yes |  |
| `company.turnover_band` | string or null | yes |  |
| `company.website_domain` | string or null | yes |  |
| `company.registered_office` | object | yes |  |
| `contacts_held` | integer (0 or more) or `under 10` or `suppressed` or null | yes | Contacts we hold at the company: a single-company count, so signed-in callers only (null otherwise) and logged. Trial callers see it rounded. |
| `contacts_by_level` | array of `LevelCount` or null | yes | The same count by job level, most senior first, with Level not known last; null when signed out. |
| `contacts_by_level[].level` | string | yes |  |
| `contacts_by_level[].contacts` | integer (0 or more) or `under 10` or `suppressed` | yes | A whole number; "under 10" when disclosure control withholds a small cell; or "suppressed" when secondary suppression hides a cell of 10 or more in a cross-tab or breakdown, so totals cannot be differenced. Anonymous and trial callers see cells rounded to the nearest 5. |
| `disclosure` | `Disclosure` | yes | Whether these numbers are exact or protected: "under 10" cells, rounding to 5 and secondary suppression for anonymous and trial callers. |
| `disclosure.level` | enum: `exact`, `rounded` | yes | exact for authenticated paid callers; rounded for anonymous and trial callers, whose counts under 100 and every cell are rounded to the nearest 5. |
| `disclosure.rounded_to` | integer or null | yes | 5 when numbers are rounded; null when they are exact. |
| `disclosure.secondary_suppression` | boolean | yes | True when cross-tab or breakdown cells of 10 or more were hidden as "suppressed" so totals cannot be differenced. |
| `disclosure.notes` | array of string | yes |  |
| `compliance` | `CompanyCompliance` | yes | The company facts of the compliance object, for results with no contact. |
| `compliance.lawful_basis` | enum: `legitimate_interests_art6_1_f` | yes |  |
| `compliance.subscriber_class` | enum: `ltd`, `plc`, `llp`, `scottish_partnership`, `public_body`, `charity_incorporated`, `sole_trader`, `ordinary_partnership`, and 1 more | yes |  |
| `compliance.corporate_subscriber` | boolean | yes |  |
| `compliance.email_marketing_basis` | enum: `pecr_corporate_subscriber`, `consent_required` | yes |  |
| `compliance.subscriber_evidence` | object | yes |  |
| `compliance.provenance` | object | yes |  |
| `compliance.attribution` | string or null | yes |  |
| `credits_charged` | `0` | yes |  |

#### Example response

```json
{
  "match_confidence": 1,
  "dataset_version": "2026-W39",
  "company": {
    "companies_house_number": "12345678",
    "name": "Example Manufacturing Ltd",
    "status": "active",
    "type": "ltd",
    "subscriber_class": "ltd",
    "incorporation_date": "2004-02-19",
    "sic_2007": [
      {
        "code": "25620",
        "label": "Machining"
      }
    ],
    "employee_band": "100-199",
    "turnover_band": "11M-20M",
    "website_domain": "example.co.uk",
    "registered_office": {
      "town": "Leeds",
      "postcode": "LS11 5AA"
    }
  },
  "contacts_held": 14,
  "contacts_by_level": [
    {
      "level": "Director",
      "contacts": 3
    },
    {
      "level": "Manager",
      "contacts": 6
    }
  ],
  "compliance": {
    "lawful_basis": "legitimate_interests_art6_1_f",
    "subscriber_class": "ltd",
    "corporate_subscriber": true,
    "email_marketing_basis": "pecr_corporate_subscriber",
    "subscriber_evidence": {
      "companies_house_number": "12345678",
      "company_type": "ltd"
    },
    "provenance": {
      "company": {
        "source": "companies_house",
        "as_of": "2026-09-21"
      }
    },
    "attribution": "Contains public sector information licensed under the Open Government Licence v3.0"
  },
  "disclosure": {
    "level": "exact",
    "rounded_to": null,
    "secondary_suppression": false,
    "notes": []
  },
  "credits_charged": 0
}
```

## Errors

Every error is a problem object with a `code` and a `next_step`. Every response carries the `RateLimit` and `RateLimit-Policy` headers; see [Rate limits](https://emailmovers.com/mydatahub/docs/rate-limits.md).

| Status | Problem codes | When |
| --- | --- | --- |
| 400 | [`invalid-request`](https://emailmovers.com/mydatahub/docs/errors/invalid-request.md), [`idempotency-key-required`](https://emailmovers.com/mydatahub/docs/errors/idempotency-key-required.md), [`unsupported-version`](https://emailmovers.com/mydatahub/docs/errors/unsupported-version.md) | The request could not be read, or an Idempotency-Key is missing. |
| 401 | [`authentication-required`](https://emailmovers.com/mydatahub/docs/errors/authentication-required.md), [`account-required`](https://emailmovers.com/mydatahub/docs/errors/account-required.md) | Sign in (OAuth) or send an API key (authentication-required), or create a free account for what the anonymous tier does not cover (account-required). |
| 422 | [`validation-failed`](https://emailmovers.com/mydatahub/docs/errors/validation-failed.md), [`quote-required`](https://emailmovers.com/mydatahub/docs/errors/quote-required.md), [`dataset-unavailable`](https://emailmovers.com/mydatahub/docs/errors/dataset-unavailable.md) | The request is not valid. errors lists every problem with a JSON pointer and did_you_mean. |
| 429 | [`rate-limited`](https://emailmovers.com/mydatahub/docs/errors/rate-limited.md) | Too many requests. Wait for Retry-After. |
| Any other failure | [`internal-error`](https://emailmovers.com/mydatahub/docs/errors/internal-error.md), [`service-unavailable`](https://emailmovers.com/mydatahub/docs/errors/service-unavailable.md), [`tps-screen-expired`](https://emailmovers.com/mydatahub/docs/errors/tps-screen-expired.md) | Something failed on our side (500 internal-error) or the service is briefly unavailable (503 service-unavailable, with Retry-After). Nothing was charged; retry with the same Idempotency-Key. A count, sample, quote or order with telephone in play is also refused with 503 tps-screen-expired, with no Retry-After, while the dataset version's TPS and CTPS screen is more than 28 days old. |
