# Career Agent: Job Search, Interview Prep & Referrals (`andrei_gruz/career-agent`) Actor

Upload your CV and target role. The agent finds matching LinkedIn vacancies, builds a 14-day interview-prep plan per job, finds people at each company who can refer you (alumni, ex-colleagues, same team) with drafted messages, and creates a personal learning course.

- **URL**: https://apify.com/andrei\_gruz/career-agent.md
- **Developed by:** [Andrei Gruzitski](https://apify.com/andrei_gruz) (community)
- **Categories:** Jobs, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Career Agent: Job Search, Interview Prep & Referrals

Upload your CV, type the role you want and your city. The Career Agent then does the job-hunting groundwork for you:

1. **Finds matching vacancies** on LinkedIn and ranks them by how well they fit your CV, with the reason for each match.
2. **Builds an interview-prep plan for every vacancy**: your skill gaps, courses and practice material, real interview questions and insights from Glassdoor where available, and a 14-day study plan.
3. **Finds people who can refer you**: alumni of your university, former colleagues and people in the same team at each company. For the best 2-3 people per vacancy it writes a short, personal message (email and LinkedIn note) asking about the role and for a referral. **Nothing is sent**: you review and send the messages yourself.
4. **Creates a personal learning course** that covers the skills most of your target vacancies ask for.

### How to use it

1. Upload your CV as a PDF (text-based, not a scan).
2. Enter your target position (e.g. "Data Scientist") and city (e.g. "Amsterdam").
3. Pick what to wait for:
   - **Vacancies only**: about 5 minutes.
   - **Everything**: about 20-40 minutes for 10 vacancies.
4. Start. Results appear in the **Output** tab.

The agent remembers your profile for your Apify account. Run it again later without a CV to look for new vacancies; only new vacancies are processed and charged. If a run stops waiting before everything is ready, the work continues in the background: run again with **Start a new search** off to collect it.

### Output

One dataset item per vacancy:

| Field | Description |
|---|---|
| `title`, `company_name`, `location`, `job_url` | The vacancy |
| `match_score`, `match_reason`, `matched_skills`, `missing_skills` | How well it fits your CV |
| `prep` | Interview-prep plan: `skill_gaps`, `courses`, `practice`, `interview_insights`, `likely_questions`, `plan` (14 days), `plan_markdown`, `data_quality` |
| `referral_status` | `drafted`, `no_contacts` or `pending` |
| `referral_contacts` | People to contact: name, LinkedIn URL, why they are relevant (`tier`, `match_reasons`), email if found (`email_status`: found / guessed), suggested `channel`, and the drafted `subject`, `body` and `linkedin_note` |

The dataset has three views: **Vacancies**, **Interview prep** and **Referral contacts**.
The learning course is in the key-value store record `OUTPUT` (`courses[].modules[]` with resources).

Example item (shortened):

```json
{
  "title": "Data Scientist",
  "company_name": "Picnic",
  "location": "Amsterdam, North Holland, Netherlands",
  "match_score": 86,
  "prep_status": "ready",
  "prep": {
    "skill_gaps": [{ "skill": "A/B testing", "why": "Mentioned three times in the posting" }],
    "likely_questions": [{ "question": "How would you design a demand forecast for a new hub?", "answer_hint": "..." }],
    "plan_markdown": "Day 1: ..."
  },
  "referral_status": "drafted",
  "referral_contacts": [
    {
      "contact_name": "...",
      "tier": "alumni",
      "match_reasons": ["University of Amsterdam, MSc Data Science 2021"],
      "channel": "linkedin",
      "linkedin_note": "Hi ..., fellow UvA alum here ..."
    }
  ]
}
```

### Pricing

You pay per result, not for waiting time:

| Event | When |
|---|---|
| Vacancy found | Each matching vacancy returned |
| Interview-prep plan | Each vacancy with a finished prep plan |
| Referral contacts | Each vacancy with drafted referral messages |
| Learning course | Each course built or updated |

Results you already received are never charged again in later runs. Set a **maximum cost per run** to stay in control; results beyond it are left out and can be collected later.

### Your data

- Your CV text and the extracted profile are stored by the Career Agent service so that later runs can continue where you left off. They are used only to run this agent.
- Referral contacts are public LinkedIn profiles of people at the companies you are applying to. Only a few people per vacancy are selected, and **no message is ever sent automatically**.
- Your profile is linked to a random id kept in your own Apify storage (key-value store `career-agent-state`). To have your data deleted, open an issue on this Actor with that id.

### Limits

- The vacancy search is tuned for the **Netherlands**.
- Prep plans use public data; for small companies there may be no interview reports, then the plan is role-based (`data_quality: "role-based only"`).
- Emails marked `guessed` are not verified. Use the LinkedIn note for those.
- When many people use the agent at the same time, your run may wait for a free slot, or ask you to try again later.

### Use it from AI agents

This Actor can be called as a tool through the [Apify MCP server](https://mcp.apify.com), e.g. from Claude or other MCP clients.

# Actor input Schema

## `cv` (type: `string`):

Upload your CV as a PDF, or paste a public URL to a PDF. Needed on the first run. On later runs you can leave it empty: the agent remembers your profile and only looks for new vacancies.

## `position` (type: `string`):

The role you are looking for, e.g. "Data Scientist" or "Electronics Engineer".

## `city` (type: `string`):

Where you want to work, e.g. "Amsterdam". The search is tuned for the Netherlands.

## `email` (type: `string`):

Used only in the signature of the drafted referral messages. Nothing is ever sent on your behalf.

## `waitFor` (type: `string`):

How long the run waits. "Vacancies" returns in about 5 minutes; "Everything" waits for interview-prep plans, referral drafts and the learning course (about 20-40 minutes for 10 vacancies). Work that is still running continues in the background: run the Actor again later with "Start a new search" off to collect it.

## `maxWaitMinutes` (type: `integer`):

The run stops waiting after this many minutes and returns what is ready.

## `startPipeline` (type: `boolean`):

On: upload the CV (if given) and start a new vacancy search. Off: only collect results from earlier runs.

## `authUserId` (type: `string`):

Only if you already use the Career Agent web app: paste your user id to work on the same profile. Leave empty to use the id this Actor created for your Apify account.

## `pollIntervalSeconds` (type: `integer`):

How often the agent checks for new results.

## Actor input object example

```json
{
  "position": "Data Scientist",
  "city": "Amsterdam",
  "waitFor": "everything",
  "maxWaitMinutes": 55,
  "startPipeline": true,
  "pollIntervalSeconds": 30
}
```

# Actor output Schema

## `vacancies` (type: `string`):

Matching vacancies with match score and reason, interview-prep status and referral status.

## `interviewPrep` (type: `string`):

14-day interview-prep plan per vacancy.

## `referrals` (type: `string`):

People who can refer you, with drafted emails and LinkedIn notes (never sent automatically).

## `allData` (type: `string`):

Every vacancy with its full prep plan and referral contacts.

## `course` (type: `string`):

Your personal learning course (modules and resources) and a run summary.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "position": "Data Scientist",
    "city": "Amsterdam"
};

// Run the Actor and wait for it to finish
const run = await client.actor("andrei_gruz/career-agent").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "position": "Data Scientist",
    "city": "Amsterdam",
}

# Run the Actor and wait for it to finish
run = client.actor("andrei_gruz/career-agent").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "position": "Data Scientist",
  "city": "Amsterdam"
}' |
apify call andrei_gruz/career-agent --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,andrei_gruz/career-agent"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/w7D7fpLnFKal2vHFE/builds/XB9HB8bUYy40Q8cFI/openapi.json
