---
name: worthpitching
description: Look up any company by domain and learn if it's worth pitching - firmographics, hiring, tech stack, ads, ICP fit score, why-now signals and a suggested opener. Use before writing outreach to a company.
---

# WorthPitching

Company research for outbound. One call per company.

## Setup

1. Ask the user for their WorthPitching API key (they create it at https://worthpitching.com/app under API keys). Keys start with `wp_live_`. No account yet? Send them to https://worthpitching.com/start to start a 7-day trial.
2. Store it as `WORTHPITCHING_API_KEY`. Never print it back in full.

## Look up a company

```bash
curl "https://worthpitching.com/api/v1/lookup?domain=acme.io" \
  -H "Authorization: Bearer $WORTHPITCHING_API_KEY"
```

Query parameters:

| Param | Required | Meaning |
|---|---|---|
| `domain` | yes | Company domain, e.g. `acme.io`. URLs are accepted and normalised. |
| `icp` | no | One sentence describing the user's ideal customer. Adds `fit`. Falls back to the ICP saved in the dashboard. |
| `fresh` | no | `true` skips the 7-day cache. Use sparingly. |

Response fields (snake_case; fields we can't fill are `null`, never guessed):

| Field | Meaning |
|---|---|
| `domain`, `name`, `description`, `industry` | What the company is |
| `employee_range`, `employee_count`, `hq_country`, `hq_city`, `founded_year` | Size and location |
| `linkedin` | `url`, `company_type`, `specialties`, `funding`, `recent_posts`, `similar_companies` (or `null`) |
| `hiring.total`, `hiring.sales`, `hiring.engineering`, `hiring.marketing`, `hiring.ops`, `hiring.posted_last_30d` | Open roles by team (or `null` when there's no public job board) |
| `tech` | Array of `{ name, category }` detected from website scripts, headers and DNS |
| `ads.active`, `ads.new_7d`, `ads.longest_running_days`, `ads.landing_pages`, `ads.ad_library_url` | Meta ads (or `null` when the ads source isn't connected) |
| `linkedin_ads` | `last_30d`, `recent`, `ad_library_url` (or `null`) |
| `google_ads` | `total`, `transparency_url` (or `null`) |
| `search` | `etv_monthly`, `organic_etv`, `paid_etv`: a search-traffic estimate, not visits (or `null`) |
| `why_now` | Array of `{ tag, text }` for signals that fired. Tags: `hiring_sales`, `hiring_marketing`, `hiring_eng`, `hiring_fast`, `scaling_ads`, `investing_marketing`, `tech_change`, `self_serve`. Empty means nothing fired. |
| `why_now_line` | One-line reason to reach out now |
| `opener` | Suggested first line, built only from a real signal |
| `fit` | `{ score, verdict, parts }`: 0-100 score against the ICP, or `null` when no ICP was passed or saved |
| `sources` | Where each field group came from (`identity`, `industry`, `hiring`, `tech`, `ads`, `linkedin`, `linkedin_ads`, `google_ads`, `search`) |
| `as_of` | When the data was fetched (ISO timestamp) |
| `no_match` | `true` when nothing was found for the domain |
| `credits_charged`, `credits_remaining` | What this call cost and the balance left |

## Watchlist and signals

- `GET /api/v1/watchlist` lists watched domains. `POST /api/v1/watchlist` with `{ "domain": "acme.io" }` or `{ "domains": [...] }` adds them. `DELETE /api/v1/watchlist?domain=acme.io` removes one.
- `GET /api/v1/signals?since=YYYY-MM-DD` returns signals for watched companies, strongest first.

Full spec: https://worthpitching.com/openapi.json

## Credits

- 50 credits per company lookup
- 0 credits when nothing is found (`no_match: true`)
- Same domain within 7 days: 0 credits (cached)
- Each watched company: 10 credits per week for the weekly rescan
- Check `credits_remaining` in every response

## MCP

If the client supports MCP, connect to `https://worthpitching.com/api/mcp` (Streamable HTTP, JSON responses, `Authorization: Bearer wp_live_...`). Tools:

- `lookup_company` (`domain`, optional `icp`): same data and billing as the REST lookup. 50 credits; 0 if nothing is found or the domain was looked up in the last 7 days.
- `get_account`: remaining credits. Free.

## Examples

User: "Is acme.io worth pitching?" -> call the lookup, answer with `fit.score`, the `why_now_line` and the `opener`.

User: "Rank these 10 companies" -> look up each, sort by `fit.score`, put companies with a non-empty `why_now` first, and show one line per company.

## Errors

Errors look like `{ "error": { "code": "...", "message": "..." } }`.

- `400 invalid_domain`: the domain is missing or not valid. Fix it before retrying.
- `401 unauthorized`: key missing or wrong. Ask the user to check it.
- `402 insufficient_credits`: out of credits. Tell the user to top up at https://worthpitching.com/app. Repeats within 7 days still work.
- `5xx`: retry with backoff.
