Hand the agent a company name or LinkedIn URL and get a full research dossier — profile, headcount growth, content pillars + SWOT from their posts, C-level execs, and open roles. Delivered as machine-readable JSON and a human-readable PDF brief.
/api/v1/companies/universal-name-to-id10 credits/call/api/v1/companies/name-lookup10 credits/call/api/v1/companies/info10 credits/call/api/v1/companies/enrich10 credits/call/api/v1/companies/employees-data10 credits/callBallpark: ~500 credits for 10 typical runs. Signup includes 300 free credits.
Download comes with your API key baked in — sign up (300 free credits, one minute) or open this skill in your dashboard.
---
name: company-deep-research
description: Use when the user wants a deep research dossier on a single company. Triggers on "research this company", "company deep dive", "build a company brief", "competitive intel on X", "analyze X as a company". Takes a company name or LinkedIn company URL and produces a full brief — firmographics, headcount + composition, positioning + SWOT, leadership, and hiring signal — as machine-readable JSON and a human-readable PDF.
---
# Company Deep Research (via Zooq)
You produce a deep research dossier on ONE company, end to end, by chaining Zooq endpoints. Use this when a user wants to understand a company for sales, competitive intelligence, investment screening, or partnership evaluation.
All calls consume Zooq credits. The user's balance and per-call cost are at https://zooq.dev/dash. On HTTP 402, tell them to top up.
## Input you need from the user
One of:
- A **LinkedIn company URL** — e.g. `https://www.linkedin.com/company/auditoriaai/`
- A **company name** — e.g. `Auditoria.AI`
If the user gave neither clearly, ask for it before doing anything.
---
## Step 1 — Resolve the company
Every later step needs the company's stable `org_` id and its `slug`.
**If you have a LinkedIn URL:** extract the slug — the segment after `linkedin.com/company/` (for the example above, the slug is `auditoriaai`). Then:
```
GET https://zooq.dev/api/v1/companies/universal-name-to-id?slug=<SLUG>
Headers:
X-API-Key: REPLACE_WITH_YOUR_KEY
```
Returns the FULL company record. Read `data.id` (an `org_...` id) and `data.slug`. Hold onto both.
**If you only have a company name:** resolve it to a company first:
```
GET https://zooq.dev/api/v1/companies/name-lookup?name=<COMPANY_NAME>
```
`name` is the query param (min 3 chars). Results are in `data[]` — each has `id` (`org_...`), `name`, `slug`, `url`, `headcount`. Pick the best match, confirm it with the user ("I found <name> — linkedin.com/company/<slug>, correct?"), then keep its `id` and `slug`.
Do not continue until you have a confirmed `org_` id and slug.
---
## Step 2 — Company firmographics
```
GET https://zooq.dev/api/v1/companies/info?id=<ORG_ID>
```
Pass the `org_` id as `id` (or pass `slug=<SLUG>` instead — either works). **The payload is now the FLAT company record directly under `data`** — there is no `data.company` wrapper anymore.
Pull the positioning and firmographics from `data`: `name`, `slug`, `url`, `tagline`, `description`, `type`, `industries`, `industries_v2`, `specialities`, `website`, `founded`, `hq_city`, `hq_country_code`, `headcount`, `headcount_range`, `follower_count`. Extract the positioning (what they do, who for) — this anchors the whole brief.
---
## Step 2b — Live enrichment (funding, offices, corporate family)
```
GET https://zooq.dev/api/v1/companies/enrich?slug=<SLUG>
Headers:
X-API-Key: REPLACE_WITH_YOUR_KEY
```
The live company read adds three things the dataset record in Step 2 does not have: **funding signals**, the **full office list** (not just HQ), and **parent / affiliated pages**. Fold them into the dossier — funding and corporate structure are usually the strongest lines in it. Not-found costs nothing on this endpoint.
## Step 3 — Headcount & composition
You already have current size from Step 2: `headcount` (exact) and `headcount_range` (band), plus `follower_count` as a reach proxy. **Remember `headcount` — Step 5 uses it to estimate cost.**
**Note on growth trajectory:** a month-by-month 6/12/24-month headcount time-series is not available in the current catalog — that data came from the `companies/insights` endpoint, which now requires a numeric company id that no endpoint yields today (an `org_` id returns HTTP 422). Do not attempt it. Instead, gauge **hiring momentum** directly from the employee record (Step 6) — recent joiners are a live, company-locked signal.
To profile composition (seniority / function / geography), sample current employees:
```
GET https://zooq.dev/api/v1/companies/employees-data?slug=<SLUG>¤t_only=true&limit=50
```
Returns professional records in `data[]` (same shape as `/search/people`) with `headline`, `geo_city`, `geo_country_code`. Paging is in `pagination{ next_cursor, has_more }`. Roll headlines up into function/seniority buckets and locations into a geo spread. Each page is one credit-consuming call — tell the user how many pages you plan to fetch before going past the first.
---
## Step 4 — Positioning & narrative + SWOT signals
The old company post-feed step is gone: a company's LinkedIn post feed lives on the Live `companies/posts` endpoint, which needs a numeric company id that no endpoint yields today (an `org_` id returns HTTP 422). So build the narrative from the **firmographic record + leadership + employee composition**, which are all live Data endpoints:
- **Positioning pillars** — from Step 2's `description`, `tagline`, and `specialities`, cluster what the company sells into 3-6 themes (e.g. product areas, target buyer, differentiators). Give each a name and cite the source phrase.
- **SWOT signals** — read the record as evidence:
- *Strengths* — proof points in the description, notable `specialities`, follower reach, senior leadership depth (Step 5).
- *Weaknesses* — gaps: thin leadership in a function, narrow geo, small headcount vs stated ambition.
- *Opportunities* — adjacent `industries_v2`/specialities they could extend into; hiring into a new function (Step 6).
- *Threats* — crowded `industries`, HQ-market concentration, scale disadvantage.
Mark each SWOT item as evidence-backed (cite the field/record) vs inference.
---
## Step 5 — Leadership / target execs
By **default** target C-level leadership. Use the company-locked employee endpoint:
```
GET https://zooq.dev/api/v1/companies/employees-data?slug=<SLUG>&title=chief¤t_only=true&limit=<N>
```
- `slug=<SLUG>` locks results to this company.
- `current_only=true` restricts to people in a current role there.
- `title=chief` is the reliable C-level filter (min 3 chars) — it matches "Chief Financial Officer", "Chief Executive Officer", etc. To also catch abbreviation-only titles, run extra passes with `title=CEO`, `title=CFO`, `title=CTO`, `title=COO` and **deduplicate by `id`** (the `prsn_` id).
- `limit` is results per page, max **50**. For more, paginate with `cursor` — pass `pagination.next_cursor` from the previous response as `cursor=<...>`; stop when `pagination.has_more` is false.
`/api/v1/search/people?organization_slugs=<SLUG>&title=chief¤t_only=true&limit=<N>` is an equivalent alternative (same record shape, same `cursor` paging) if you want cross-company filters.
**Before running, if the user gave no specific instruction, ASK two things:**
1. **Which titles?** C-level only (default), or specific titles (e.g. "VP Sales", "Engineering"), or everyone?
2. **How many people?** A fixed number, or all of them?
If they want "all" of a broad set, estimate the cost first: take `headcount` from Step 2, divide by 50 (the max page size), round up — that's the number of credit-consuming calls. Show the user that call count and **get confirmation before running**. Example: 134 employees ÷ 50 ≈ 3 calls.
Each person record has `id` (`prsn_...`), `handle`, `url`, `first_name`, `last_name`, `headline`, `geo_city`, `geo_country_code`, `profile_pictures`.
---
## Step 6 — Hiring signal
There is no dedicated company-locked open-roles feed in the current catalog — job search (`/search/jobs`) filters by a numeric organization id that no endpoint yields today, so you cannot reliably pull *this* company's postings. Instead read hiring momentum from the employee record, which IS company-locked:
```
GET https://zooq.dev/api/v1/companies/employees-data?slug=<SLUG>¤t_only=true&sort=newest&limit=<N>
```
- `sort=newest` surfaces the most-recently-joined current employees — a batch of recent senior hires is a strong expansion signal.
- Add `start_year=<YEAR>` (optionally `start_month=<1-12>`) to count joiners since a cutoff.
- Note which **functions** (from `headline`) and **locations** (from `geo_city`) the company is adding into — that is the demand/expansion read.
*(Optional, best-effort, NOT company-locked:* `/api/v1/search/jobs?keyword=<TERM>&count=<N>` returns live postings that match a keyword across all employers — useful for market/role context, but it will include other companies, so never present it as the target company's own roles.*)*
---
## Step 7 — Output
Produce **both** formats.
### a. JSON (for the next agent / automation step)
A single object so a downstream step can parse it directly:
```json
{
"company": { "id": "org_...", "name": "...", "slug": "...", "url": "...", "tagline": "...", "description": "...", "industries": [], "specialities": [], "website": "...", "founded": 0, "hq": { "city": "...", "countryCode": "..." } },
"headcount": { "exact": 0, "range": "...", "followerCount": 0, "growthTimeSeries": null },
"content": {
"pillars": [ { "name": "...", "sourceField": "description|tagline|specialities", "note": "..." } ],
"swot": {
"strengths": [ { "point": "...", "evidence": "record|inference" } ],
"weaknesses": [],
"opportunities": [],
"threats": []
}
},
"execs": [ { "id": "prsn_...", "fullName": "...", "headline": "...", "geoCity": "...", "linkedinUrl": "..." } ],
"hiringSignal": { "recentJoiners": [ { "fullName": "...", "headline": "...", "geoCity": "..." } ], "functionsAdding": [], "note": "..." },
"generatedAt": "ISO-8601"
}
```
`growthTimeSeries` is `null` by design — the month-by-month series isn't available in the current catalog (see Step 3). Don't fabricate it.
### b. Company brief — PDF (the default deliverable)
Unless the user only asked for JSON, also produce a human-readable **company brief**. Build it as a clean, sectioned document and render it to **PDF** if your environment can (HTML→PDF, a document tool, etc.); if you cannot produce a PDF, deliver the brief as polished Markdown and say so.
Brief structure:
1. **Cover** — company name, tagline, LinkedIn URL, date.
2. **Snapshot** — one paragraph: what they do, who for, headcount + follower reach.
3. **Firmographics** — industry, specialities, HQ, founded year, current headcount + band.
4. **Positioning & narrative** — the positioning pillars, each with its source phrase.
5. **SWOT** — a four-quadrant table; evidence-backed items first.
6. **Leadership** — the execs found, name + title + location.
7. **Hiring signal** — recent joiners grouped by function/location, with the momentum read.
8. **Analyst take** — 3-5 sentences: what this company is, momentum, and the single most useful insight for the reader.
---
## Don't do
- **Don't skip the Step 5 questions.** Asking titles + headcount up front prevents surprise credit spend. The only exception is when the user already specified both.
- **Don't fabricate.** If an endpoint returns `success: false` or empty data, say so in the brief — never invent execs, pillars, or hires. In particular, never invent a headcount growth time-series (it isn't available) or company job postings.
- **Don't mark inference as fact.** Every SWOT point is tagged evidence-backed or inference.
- **Don't paginate employees or people past what the user approved.** Confirm the page/call count first.
- **Don't call the retired paths.** `companies/insights` and `companies/posts` need a numeric id no endpoint yields (they 422 on an `org_` id); `search/jobs` can't be locked to one company. Stick to the Data endpoints above.
- **Don't put the API key in any output.** It's already wired into this skill file.
## Rate limits & refunds
- HTTP 429 → you're going too fast; wait 30 seconds and retry once. Space bulk pagination calls out.
- HTTP 5xx → Zooq auto-refunds the credits; surface the error, don't hammer-retry.
- HTTP 402 → out of credits; send the user to https://zooq.dev/dash/billing.