Now out of stealth: the missing link between AI agents and LinkedIn data.
All skills

Company Deep Research

Premium
research

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.

Endpoints it uses

  • /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/call

Ballpark: ~500 credits for 10 typical runs. Signup includes 300 free credits.

Run this skill

Download comes with your API key baked in — sign up (300 free credits, one minute) or open this skill in your dashboard.

What's inside (full preview)

---
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>&current_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&current_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&current_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>&current_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.