URL: /code/data/organizations/enrich · Id: `page:/code/data/organizations/enrich`

# Organization.enrich

> Fill in what a company is, what it runs and what happened there lately, from its domain alone.

`POST https://api.sb/{your-domain}/organizations/enrich`

Fill in what a company is, what it runs and what happened there lately, from its domain alone.

- **Price:** 20¢ per 100 companies
- **Success rate:** 99.98% of 569,418 calls
- **Freshness:** Fresh for 30 days
- **Emits:** `Organization.enriched`
- **Capability:** [Enrichment](https://startupbuilder.dev/systems/sales/enrichment)

```text title="Run it · Ask"
What does harborview-pm.com run, and what happened there lately? Spend up to 10¢.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Organization.enrich({ hostnames: ['harborview-pm.com'], fields: ['profile', 'technologies', 'events'], maxCost: 0.1 })
```

```json title="Run it · Response"
{
  "organizations": [
    {
      "hostname": "harborview-pm.com",
      "name": "Harborview Property Management",
      "description": "Residential property management for Puget Sound owners.",
      "industry": "Real estate",
      "headcount": 34,
      "founded": 2009,
      "country": "US",
      "region": "US-WA",
      "socials": {
        "linkedin": "https://www.linkedin.com/company/harborview-pm"
      },
      "technologies": [
        {
          "name": "QuickBooks",
          "category": "Accounting",
          "firstSeen": "2024-03-02",
          "evidence": "job-post"
        },
        {
          "name": "WordPress",
          "category": "Website",
          "firstSeen": null,
          "evidence": "page"
        }
      ],
      "events": [
        {
          "kind": "opened-location",
          "date": "2026-09-30",
          "summary": "Opened a second office in Tacoma.",
          "url": "https://harborview-pm.com/news/tacoma"
        }
      ],
      "filled": [
        "profile",
        "technologies",
        "events"
      ],
      "observedAt": "2026-10-27T14:02:11Z",
      "method": "sampled"
    }
  ],
  "cost": {
    "usd": 0,
    "maxUsd": 0.082,
    "units": 3,
    "misses": 0
  }
}
```

## Options and prices
| You get | Input that selects it | Price | Success rate |
| --- | --- | --- | --- |
| Company profile | `{"fields":["profile"]}` | About 20¢ per 100 companies | 99.98% of 569,418 calls |
| The products a company runs | `{"fields":["technologies"]}` | About 4¢ a company | 99.9% of 8,842 calls |
| Headcount and its trend | `{"fields":["headcount"]}` | About 5¢ a company | 100% of 4,379 calls |
| Open roles | `{"fields":["hiring"]}` | About 1¢ a company | 97.3% of 10,852 calls |
| What happened there lately | `{"fields":["events"]}` | About 1¢ a company | 99.98% of 34,785 calls |

## Inputs
| Name | Type | Default | Meaning |
| --- | --- | --- | --- |
| `hostnames` | [`Hostname[]`](/code/data/types#hostname) | None. | Up to 50 company domains, no scheme. Pass this or `organization`. |
| `organization` | `Organization` | None. | A saved Organization id; its domain is read. Also served at `/organizations/{organization}/enrich`. |
| `fields` | `('profile' \| 'technologies' \| 'headcount' \| 'hiring' \| 'events')[]` | `['profile']` | What to fill. Each field is its own job with its own price. |
| `since` | `string` | `'90d'` | How far back `hiring` and `events` look. |
| `maxCost` | `number` | `0.50` | The most this domain may spend, in USD. Over it, the call is refused before it spends, or stops early with what it has. |

## Outputs
| Field | Type | What `null` means |
| --- | --- | --- |
| `organizations` | `Organization[]` | Never null: one row per domain sent. |
| `organizations[].hostname` | [`Hostname`](/code/data/types#hostname) | Never null. |
| `organizations[].name` | `string` | Never null when the domain is known; a domain no source knows returns only `hostname` and `filled: []`, at $0. |
| `organizations[].description` | `string \| null` | Unknown. |
| `organizations[].industry` | `string \| null` | Unknown. |
| `organizations[].headcount` | `number \| null`, in people | Unknown, never zero. |
| `organizations[].headcountTrend` | `{ months: 6 \| 12 \| 24; change: number }[]`, in share, 0.21 is +21% | Absent without `headcount` in `fields`. |
| `organizations[].founded` | `number \| null`, in year | Unknown. |
| `organizations[].country` | `string \| null`, in ISO 3166-1 | Unknown. |
| `organizations[].region` | `string \| null`, in ISO 3166-2 | Unknown. |
| `organizations[].socials` | `{ linkedin?: string; x?: string; facebook?: string }` | Never null: a missing key means no profile was found on that site. |
| `organizations[].technologies` | `{ name: string; category: string; firstSeen: string \| null; evidence: 'page' \| 'job-post' \| 'dns' \| null }[]` | Absent without `technologies`. `firstSeen: null` means seen, date unknown. |
| `organizations[].hiring` | `{ title: string; postedAt: string; url: string; location: string \| null }[]` | Absent without `hiring`; empty means no open role in `since`. |
| `organizations[].events` | `{ kind: string; date: string; summary: string; url: string }[]` | Absent without `events`; empty means nothing dated in `since`. A `funded` event carries the round. |
| `organizations[].filled` | `string[]` | Never null: the fields this call filled, so a miss is visible. |
| `organizations[]` | [`Observed`](/code/data/types#observed) | Each row also carries `observedAt` and `method`. |
| `cost` | [`Cost`](/code/data/types#cost), in USD | Never null. In try mode `usd` is 0 and `maxUsd` is what the call would have cost. |

## Read the result
| Field | Value | What it means | What to do |
| --- | --- | --- | --- |
| `events` | A dated event in the last 30 days | You have a reason to write that is not about you. | Open the first email with it; a list with a dated reason is planned to reply at twice the rate of one without. (our planning number, measured by a 50/50 split in month 1) |
| `hiring` | A role your product replaces | They are about to pay a salary for the job your product does. | Write while the role is open; `postedAt` dates it, and the `url` is your evidence line. (the trigger rule for cold email) |
| `technologies` | `evidence: page` only | A homepage tag, not proof they use it day to day. | Trust `job-post` evidence first: a role that names the product shows daily use. (reviews of the homepage-only read: 6% called it useful) |
| `filled` | Missing a field you asked for | No source holds it for this domain; you were not billed for it. | Read it from their site with `Page.audit`, or leave it unknown. (the contract every data call keeps) |

## Effects
**Action class**

None: it reads, so no approval rule names it

**Modes**

- `try`: Runs the read and returns real rows; nothing is saved and nothing is billed.
- `send`: Returns a pending Action at once; its Event carries the rows when the read finishes.
- `do`: Waits for the read and returns the rows, billed per result.

**Idempotency**

The same `Idempotency-Key` with the same input replays the first answer at $0; with other input it returns 409.

**Saved or shared**

Nothing is written to your records unless the domain is a saved Organization. Company facts are shared across startups for 30 days.

**Emits**

`Organization.enriched` with `{ organizations, fields }, plus one Organization.funded or Organization.hiring Event per new dated fact`

**Performed by**

[Prospector](https://startupbuilder.dev/agents/sales/prospector)

**Price**

About 20¢ per 100 companies. Free: a domain no source knows. `maxCost` defaults to 50¢. The products 100 fitting companies run: 100 × 4¢ a company is about $4.00.

**Reliability**

The first route succeeds 99.98% of 569,418 calls. If it fails, a second route answers at 99.99% of 277,240 calls, and you pay for one.

**Freshness**

A reading younger than 30 days returns at $0. Readings are shared across startups for the same subject and locale.

**Batch and pages**

Up to 50 domains a call. It answers in one response.

**Rate**

[The shared rate rules](/code/data#rate): 10 calls a second per key, and an array input counts as one call.

## Refuses when
This call has no refusals of its own. Every data call can also meet [the shared data-call refusals](/code/refusals#data-calls): [`filter-unsupported`](/code/refusals#filter-unsupported), [`input-missing`](/code/refusals#input-missing), [`limit-exceeded`](/code/refusals#limit-exceeded), [`max-cost`](/code/refusals#max-cost), [`rate-limited`](/code/refusals#rate-limited), [`sources-busy`](/code/refusals#sources-busy), [`venue-unsupported`](/code/refusals#venue-unsupported).

## When it waits
Returns in one response; nothing waits.

## Example

**Ask**

```text
What does harborview-pm.com run, and what happened there lately? Spend
up to 10¢.
```

**API**

```bash
curl -X POST "https://api.sb/leaseline.app/organizations/enrich?mode=try" \
  -H "Authorization: Bearer $SB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hostnames":["harborview-pm.com"],"fields":["profile","technologies","events"],"maxCost":0.1}'
```

The response is the one in the Run it window above.

**CLI**

```bash
npx startup-builder do Organization.enrich --try --data '{"hostnames":["harborview-pm.com"],"fields":["profile","technologies","events"],"maxCost":0.1}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "mode": "try",
    "code": "return await $.Organization.enrich({ hostnames: ['harborview-pm.com'], fields: ['profile', 'technologies', 'events'], maxCost: 0.1 })"
  }
}
```

**SDK**

```ts
import { $ } from 'startup-builder'

const result = await $.try.Organization.enrich({
  hostnames: ['harborview-pm.com'],
  fields: ['profile', 'technologies', 'events'],
  maxCost: 0.1,
})
```

To retry, send the same `Idempotency-Key`: the retry returns the first answer for $0. A new key reads again.

A `sk_test_` key answers these the same way every time, at $0 ([every test value](/code/data#test-values)).

| Test value | Always returns | What it is for |
| --- | --- | --- |
| `harborview-pm.com` | `{"name":"Harborview Property Management","hostname":"harborview-pm.com","industry":"Real estate","headcount":34,"founded":2009,"country":"US","region":"US-WA"}` | Enriches to the same Harborview profile every time: 34 staff, founded 2009, in Washington. |
| `maxCost: 0.0001` | Refuses with [`max-cost`](/code/refusals#max-cost) | Any priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap. |
| `rate-limited.test` | Refuses with [`rate-limited`](/code/refusals#rate-limited) | Any call naming this hostname answers 429 with Retry-After, so your retry logic runs. |
| `sources-busy.test` | Refuses with [`sources-busy`](/code/refusals#sources-busy) | Any call naming this hostname answers 503 as if every route were busy, and nothing is spent. |

Watch it on a schedule: a Monitor runs this call and records an Event only when the reading changes.

```ts
await $.Monitor.create({
  verb: 'Organization.enrich',
  input: { hostnames: ['harborview-pm.com'], fields: ['events', 'hiring'] },
  change: 'hiring',
  every: '1w',
})
```

## Used by
- **Workflows:** [Champion moved](/capabilities/keep-and-grow/champion-moved) · [Inbound routing](/capabilities/convert-visitors/inbound-routing) · [Buying-trigger feed](/capabilities/find-customers/buying-trigger-feed) · [List refresh](/capabilities/find-customers/list-refresh) · [Who is visiting](/capabilities/convert-visitors/whos-visiting)
- **Agent tasks:** [Account brief](/capabilities/reach-out/account-brief) · [Answer every inbound](/capabilities/convert-visitors/answer-every-inbound)

## Related
[`Organization.count`](/code/data/organizations/count) · [`Organization.find`](/code/data/organizations/find) · [`Organization.resolve`](/code/data/organizations/resolve)