# A Clearbit alternative that needs no HubSpot

New Clearbit sign-ups need a HubSpot account, and Breeze Intelligence works inside HubSpot. How to get company data by domain into your own code instead.

## What changed

- HubSpot bought Clearbit at the end of 2023. Since December 2023,
  [new Clearbit sign-ups need a HubSpot account](https://clearbit.com/changelog). Customers who signed up
  before then keep their access.
- In September 2024, Clearbit's enrichment became Breeze Intelligence, which
  [works inside HubSpot](https://knowledge.hubspot.com/records/get-started-with-data-enrichment).
- On April 30, 2025, Clearbit
  [switched off its free tools](https://help.clearbit.com/hc/en-us/articles/31990018203031-Clearbit-Free-Tools-Sunset-April-30th-2025).

So if you're starting out, need company data in your own code, and don't run on HubSpot, Clearbit isn't
an option any more.

## What a replacement has to do

Clearbit's company lookup had one job: send a domain, get the company back. A replacement should do the
same, and fit code that runs without anyone watching:

1. Take a domain, or any URL on it.
2. Return the same shape for every company, so your code never has to guess which fields exist.
3. Say so clearly when there's no company at the domain.
4. Bill per call, with no CRM seat and no annual contract.

## Doing it with HappyFetch

One call with the domain:

```bash tab="cURL"
curl https://api.happyfetch.net/v1/domain --max-time 120 \
  -H "Authorization: Bearer $HAPPYFETCH_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"domain":"stripe.com"}'
```

```javascript tab="JavaScript"
const res = await fetch("https://api.happyfetch.net/v1/domain", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(), // send the same key when you retry this call
  },
  body: JSON.stringify({
    "domain": "stripe.com"
  }),
  signal: AbortSignal.timeout(120_000),
});
const { data, meta, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
console.log(meta.request_id, meta.cache.status, data);
```

```python tab="Python"
import os, uuid, requests

res = requests.post(
    "https://api.happyfetch.net/v1/domain",
    headers={
        "Authorization": f"Bearer {os.environ['HAPPYFETCH_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),  # send the same key when you retry this call
    },
    json={
      "domain": "stripe.com"
    },
    timeout=120,
)
body = res.json()
if not res.ok:
    raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["meta"]["request_id"], body["meta"]["cache"]["status"])
```

The complete answer for stripe.com:

```json title="200 OK"
{
  "data": {
    "name": "Stripe",
    "tagline": "Help increase the GDP of the internet.",
    "description": "Stripe builds programmable financial services. Millions of companies—from the world’s largest enterprises to the most ambitious startups—use Stripe to accept payments, grow their revenue, and accelerate new business opportunities. Headquartered in San Francisco and Dublin, the company aims to increase the GDP of the internet.",
    "industry": "Technology, Information and Internet",
    "websiteUrl": "https://stripe.com",
    "phone": null,
    "logo": "https://media.licdn.com/dms/image/v2/D560BAQE2ZfJyfn-VCg/company-logo_200_200/B56ZlyKwpUKIAI-/0/1758557047806/stripe_logo?e=2147483647&v=beta&t=En4Hm6NDGbDTYCoOQ0Ko5Ne2gylx0WRb0yL2GlOeXBQ",
    "backgroundUrl": "https://media.licdn.com/dms/image/v2/D563DAQFt98MykXcktg/image-scale_191_1128/B56Z352EMMKIAY-/0/1778013193531/stripe_cover?e=2147483647&v=beta&t=UwiZWbPrYkD77DpQmZIjVuuqKMCfyZ-e-YcHE336MlY",
    "followerCount": 1721407,
    "employeeCount": 16594,
    "employeeCountRange": {
      "start": 5001,
      "end": 10000
    },
    "foundedOn": {
      "year": 2010
    },
    "headquarter": {
      "city": "South San Francisco",
      "country": "US",
      "geographicArea": "California",
      "postalCode": "94080",
      "street1": "354 Oyster Point Blvd",
      "street2": null
    },
    "locations": [
      {
        "city": "South San Francisco",
        "country": "US",
        "postalCode": "94080",
        "state": "California",
        "street1": "354 Oyster Point Blvd",
        "street2": null
      }
    ],
    "specialities": [],
    "universalName": "stripe",
    "linkedInUrl": "https://www.linkedin.com/company/stripe",
    "linkedInId": "2135371"
  },
  "meta": {
    "request_id": "c41d7e02-5b8a-4f3c-9e61-7a2d0b95f4e8",
    "endpoint": "domain",
    "credits_charged": 4,
    "credits_remaining": 196,
    "cache": {
      "status": "miss",
      "age_seconds": 0,
      "fetched_at": "2026-09-22T17:40:00.000Z",
      "max_age_seconds": 604800
    },
    "content_hash": "sha256:5da96e23d8f77cc3b21e33ef47ed3f0086328e61fdf427f2941e351f56af9554",
    "canonical": {
      "slug": "stripe",
      "id": "2135371"
    },
    "resolved": {
      "domain": "stripe.com",
      "verified": true
    }
  }
}
```

- **Any URL on the site works.** `https://www.stripe.com/pricing` is looked up as `stripe.com`.
- **Check the match.** Every answer says whether the company's own website is on that domain.
- **A clear no.** When there's no company at the domain, you get a clear answer that there's none, and
  why: nothing answers there, or the site has no LinkedIn company page.
- **Every field, every time.** All 18 fields are always there, the company's LinkedIn page among them,
  and empty when a value isn't known.

## Moving your code over

1. **Wrap the call** in one function, so the rest of your code doesn't care where the data comes from:

```python
import os

import requests

API = "https://api.happyfetch.net"


def company_by_domain(domain: str) -> dict | None:
    res = requests.post(
        f"{API}/v1/domain",
        headers={"Authorization": f"Bearer {os.environ['HAPPYFETCH_API_KEY']}"},
        json={"domain": domain},
        timeout=120,
    )
    if res.status_code == 404:
        return None  # no company at this domain
    res.raise_for_status()
    return res.json()["data"]
```

2. **Map the fields** you used. Our [Clearbit comparison](/compare/clearbit-alternative) has the field
   map, from Clearbit's company object to ours.
3. **Keep one key per company.** Store the company's numeric id: every URL and domain of the same company
   leads back to it, and it stays the same when a company renames.

## What it costs

| Lookups a month | Smallest pack (Starter) | Biggest pack (Business) |
|---|---|---|
| 1,000 lookups by website domain | $2.00 | $1.00 |
| 10,000 lookups by website domain | $20.00 | $10.00 |
| 100,000 lookups by website domain | $200.00 | $100.00 |

Every lookup fetched fresh, at 4 credits each. Lookups our cache answers cost half. A confirmed not-found costs the same, and nothing from our cache. Starter: $10 for 20,000 credits. Business: $500 for 2,000,000 credits. Credits never expire.

That's $1.00 per 1,000 domains on our biggest pack, and half that for
companies already in our cache. If you have the company's LinkedIn URL, it's
$0.50 per 1,000. Credits are prepaid and stay in your workspace until you use
them. There's no HubSpot plan to buy.

## When Breeze Intelligence is the better choice

If your team already works in HubSpot and wants enrichment inside the CRM without writing code, Breeze
Intelligence is built for exactly that. HappyFetch is for the other case: company data in your own code,
priced per call.
