Metadata-Version: 2.5
Name: langchain-groundtruth
Version: 0.2.0
Summary: LangChain tools for the Ground Truth company API: look up a company from its domain (registrar, DNS, tech stack, hiring), read the contact details it publishes, list newly formed US businesses with their websites, follow what changed at a company, and search tracked companies.
Project-URL: Homepage, https://companyfacts.dev
Project-URL: Documentation, https://companyfacts.dev/llms.txt
Project-URL: Pricing, https://companyfacts.dev/pricing
License: MIT
License-File: LICENSE
Keywords: ai-agents,business-registry,company-data,company-enrichment,company-lookup,company-search,contact-info,domain-lookup,hiring-data,langchain,langchain-tools,new-businesses,tech-stack
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: groundtruth-company>=0.2.0
Requires-Dist: langchain-core>=1.0.0
Description-Content-Type: text/markdown

# langchain-groundtruth

LangChain tools that look up a company from its website domain: who runs the domain, what its website runs on, whether it is hiring, and how to reach it. Also newly formed US businesses with their websites, what changed at a company, and a search over tracked companies. Every item in the answer links to the page or record it came from.

```
pip install -U langchain-groundtruth
```

Python 3.10+ (the minimum for `langchain-core`). Works without a key on the free tier (10 calls a day).

## Two lines

```python
from langchain_groundtruth import GroundTruthCompanyLookup

print(GroundTruthCompanyLookup().invoke({"domain": "stripe.com"}))
```

## The tools

| Class | Tool name | Input | Returns |
|---|---|---|---|
| `GroundTruthCompanyLookup` | `groundtruth_company_lookup` | `domain`; optional `name`, `country`, `ticker` | JSON: registrar and DNS record, email provider, tech stack, hiring (open roles, salary ranges where published, roles opened and closed in the last 30 days). With `name` and `country` the official register entry; with `ticker` revenue reported to the SEC. A part with nothing to report is listed under `missing` with the reason |
| `GroundTruthCompanyContacts` | `groundtruth_company_contacts` | `domain` | JSON: phone numbers, role inboxes such as `sales@`, contact page, postal address, read from the company's own website. For US companies also the other addresses it published at its own domain. Nothing is guessed from a name pattern |
| `GroundTruthNewBusinesses` | `groundtruth_new_businesses` | all optional: `mode` (new, search, lookup), `states` (NY, CO, OR, CT), `since`, `until`, `name`, `entity_numbers`, `entity_type`, `status`, `limit` | JSON: businesses from the New York, Colorado, Oregon and Connecticut Secretary of State registers. `new` lists those formed in a date window (default the last 7 days), `search` finds them by legal name, `lookup` by entity number. Each record has type, status, formation date, city, state, ZIP, a link to the state's record, and the company's website when one was found with proof (`website_status`: found, no website found, not checked yet). Never people's names, emails, phones or street addresses |
| `GroundTruthCompanyChanges` | `groundtruth_company_changes` | `domain`, `company`, or `state` with `entity_number`; optional `since`, `until`, `parts`, `limit` | JSON: what changed at one company, day by day: job roles opened and closed, phones, role inboxes, contact page and address on its own site, technologies added or dropped, register status. Each change has a source link. The first call starts tracking, so contact and tech changes show up on later calls |
| `GroundTruthCompanySearch` | `groundtruth_company_search` | all optional: `state`, `city`, `name`, `tech`, `formed_since`, `formed_until`, `has` (phone, role_email, contact_page), `hiring`, `limit`, `offset` | JSON: tracked companies (newly formed NY, CO, OR and CT businesses with a website found with proof) matching the filters: register details, website, technologies, job board. Whether contact details exist, not the values |

All are `BaseTool` subclasses with pydantic input schemas, sync and async.

## Agent example

```python
from langchain.agents import create_agent
from langchain_groundtruth import GroundTruthCompanyContacts, GroundTruthCompanyLookup

agent = create_agent(
    model="openai:gpt-5.5",  # any chat model you have configured
    tools=[GroundTruthCompanyLookup(), GroundTruthCompanyContacts()],
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "Is stripe.com hiring, and what does its website run on?"}]}
)
print(result["messages"][-1].content)
```

## Key

```bash
export GROUNDTRUTH_API_KEY="your-key"
```

or pass it in: `GroundTruthCompanyLookup(api_key="your-key")`. Without a key you get 10 calls a day per caller, no sign-up.

| | |
|---|---|
| Free tier | 10 calls a day, no key |
| $10 once | 2,000 calls that never expire. [Buy](https://buy.stripe.com/dRm7sM04G4iManHeO51Jm00) |
| $49 a month | 20,000 calls a month. [Buy](https://buy.stripe.com/9B6aEYg3EbLe8fz35n1Jm01) |

A company lookup, new-businesses call, change feed or company search uses 2 of a key's calls, a contacts lookup 4. A call that fails is not charged. Live prices: https://companyfacts.dev/pricing

## Errors

A failed call does not crash the agent. The tools set `handle_tool_error`, so the message comes back as the tool result (a `ToolMessage` with status `error`) and the model can read it and tell the user. That covers a spent free allowance (the message includes where to buy a key), a malformed domain, a site that blocks automated readers, a domain with nothing found, and an upstream source being down.

```python
tool = GroundTruthCompanyLookup()
print(tool.invoke({"domain": "stripe.com"}))
# If the free allowance is used up this prints the explanation and the buy link, it does not raise.
```

To get exceptions instead, set `handle_tool_error=False`.

## Options

| Argument | Default | |
|---|---|---|
| `api_key` | `GROUNDTRUTH_API_KEY` env var, else none | Stored as a secret, never shown in `repr` |
| `base_url` | `https://companyfacts.dev` | Point at another deployment |
| `timeout` | `60.0` | Seconds per call. A company lookup runs several checks in parallel |

## Tests

```
pip install -e ../groundtruth-company -e . pytest pytest-asyncio pytest-socket langchain-tests
python -m pytest tests/unit_tests
GROUNDTRUTH_LIVE=1 python -m pytest tests/integration_tests   # calls the real API
```

The unit tests run LangChain's standard `ToolsUnitTests` and `ToolsIntegrationTests` suites, plus behaviour tests, with the HTTP layer faked.

## Other ways in

The same data is available as a Python client ([`groundtruth-company`](https://pypi.org/project/groundtruth-company/)), a remote MCP server at `https://companyfacts.dev/mcp`, and plain REST. Docs: https://companyfacts.dev/llms.txt

MIT licensed.
