# Company data in n8n

Enrich companies in an n8n workflow with one HTTP Request node: by website or LinkedIn company URL, with safe retries and errors you can route.

## The node

Add an **HTTP Request** node after the node that has your companies, one item per company.

| Setting | Value |
|---|---|
| Method | `POST` |
| URL | `https://api.happyfetch.net/v1/domain` |
| Authentication | Generic Credential Type, then **Header Auth** |
| Header Auth credential | Name `Authorization`, Value `Bearer ` followed by your key from the console |
| Send Body | On, Body Content Type `JSON`, Specify Body `Using JSON` |
| JSON | `{ "domain": "{{ $json.domain }}" }` |
| Send Headers | On: `Idempotency-Key` = `{{ $json.domain }}-{{ $execution.id }}` |

Replace `$json.domain` with the field that holds the website in your items. To start from a LinkedIn
company URL, use `https://api.happyfetch.net/v1/company` and `{ "url": "{{ $json.linkedin }}" }` instead: a company lookup
costs 2 credits, against 4 credits for a domain lookup.

That key makes retries safe: within one run of the workflow, the same domain is one key, so
a retry after a timeout gets the stored answer back instead of paying twice. The next run is a new key, so
it really looks the company up again, for example after you top up your credits.

## Options that matter

- **Batching:** Items per Batch `2`, Batch Interval `1000` ms. Raise it once most of your companies come
  from our cache. Every authenticated response carries `RateLimit` headers, and a 429 is never charged.
- **Settings > Retry On Fail:** on, Max Tries `3`, Wait Between Tries `5000` ms. A call we couldn't
  complete is refunded in the same request and is safe to retry.
- **Settings > On Error:** `Continue (using error output)`. A domain without a company comes back as a 404
  with `error.code` `not_found`: an answer, not a failure, so route it to its own branch instead of
  stopping the workflow.

## Use the answer

The node's output is the API's JSON: the company under `data`, and what the call cost under `meta`. Every
field of the [company profile](/docs/company) is always present, and `null` when it isn't known. Fields
inside another one, like the headquarters' city, need `?.` because the outer one can be `null`:

| Field | Expression |
|---|---|
| Name | `{{ $json.data.name }}` |
| Employees | `{{ $json.data.employeeCount }}` |
| Size band | `{{ $json.data.employeeCountRange?.start }}`–`{{ $json.data.employeeCountRange?.end }}` |
| Industry | `{{ $json.data.industry }}` |
| Headquarters | `{{ $json.data.headquarter?.city }}, {{ $json.data.headquarter?.country }}` |
| LinkedIn page | `{{ $json.data.linkedInUrl }}` |
| Credits this call cost | `{{ $json.meta.credits_charged }}` |

A complete response is in the [domain lookup reference](/docs/domain).

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