> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pensar.dev/apex/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pensar.dev/apex/_mcp/server.

# runTargetedPentestAgent

> Run a focused pentest against one target with explicit testing objectives

**`Signature`**

```ts title="Signature"
function runTargetedPentestAgent(
  input: PentestAgentInput,
): Promise<TargetedPentestResult>;
```

Runs a single pentest orchestrator against one `target`, with no attack surface discovery. The orchestrator plans its work from your `objectives`, spawns a worker agent per objective, and documents the vulnerabilities it confirms. This is what `pensar targeted-pentest` runs, and what `runPentestAgent` runs for each discovered endpoint.

If you don't pass an `eventBus`, the agent's text and tool calls are printed to stdout. A short summary of the findings and artifact paths is always printed when the run finishes.

**`Import`**

```ts title="Import"
import { runTargetedPentestAgent } from "@pensar/apex/core/api";
```

## Parameters

**`target`** `string` — required

URL or host to test.

---

**`objectives`** `string[]` — required

One or more testing objectives, for example `"Test /api/users for SQL injection"`.

---

**`session`** `SessionInfo` — required

Session for artifacts and run configuration. See [`sessions.create()`](/apex/sdk/reference/sessions).

---

**`model`** `AIModel` — required

Model ID. See [Models](/apex/sdk/configuration#models).

---

**`authConfig`** `AIAuthConfig`

AI provider credentials. See [Configuration](/apex/sdk/configuration).

---

**`context`** `string`

Free-form context for the agent prompt, such as the application's name and purpose. The agent follows non-malicious instructions in it as guidance.

---

**`eventBus`** `AgentEventBus`

Streaming events. When omitted, output is printed to stdout. See [AgentEventBus](/apex/sdk/reference/agent-event-bus).

---

**`abortSignal`** `AbortSignal`

Cancels the run.

---

**`findingsRegistry`** `FindingsRegistry`

Shared registry that deduplicates findings across several concurrent agents.

---

**`findingPolicy`** `'native' | 'external'` — default: native

`external` skips Apex's finding judge and returns `reportedFindings` instead.

---

**`reasoning`** `ReasoningSetting`

Extended-thinking setting. See [Reasoning](/apex/sdk/configuration#reasoning).

---

> **Tip**
>
> To run the agent as one worker that tests every objective itself, with no per-objective sub-agents, create the session with `config: { disableSubagents: true }`. It's cheaper and faster, but less thorough.

## Returns

`Promise<TargetedPentestResult>`

**`findings`** `Finding[]`

Documented vulnerabilities. Same shape as [`runPentestAgent` findings](/apex/sdk/reference/run-pentest-agent#returns).

---

**`objectiveResults`** `{ objective: string; completed: boolean; result?: string }[]`

Per-objective status. `completed` is `false` when an objective needs more testing.

---

**`newObjectives`** `string[]`

Follow-up objectives the agent suggests for a future run.

---

**`reportedFindings`** `string[]`

Only set when `findingPolicy` is `external`.

---

**`findingsPath`** `string`

Absolute path to the session's `findings/` directory.

---

**`pocsPath`** `string`

Absolute path to the session's `pocs/` directory.

---

## Example

```ts
import { buildAuthConfig } from "@pensar/apex/core/ai";
import { runTargetedPentestAgent } from "@pensar/apex/core/api";
import { config } from "@pensar/apex/core/config";
import { sessions } from "@pensar/apex/core/session";

const target = "https://staging.example.com/api/orders";
const session = await sessions.create({
  name: "Orders API",
  targets: [target],
  config: {
    authCredentials: {
      username: "tester@example.com",
      password: process.env.TEST_PASSWORD,
      loginUrl: "https://staging.example.com/login",
    },
  },
});

const { findings, objectiveResults } = await runTargetedPentestAgent({
  target,
  objectives: [
    "Test for IDOR when reading another user's orders",
    "Test order creation for mass assignment",
  ],
  session,
  model: "claude-opus-4-6",
  authConfig: buildAuthConfig(await config.get()),
});

for (const r of objectiveResults ?? []) {
  console.log(`${r.completed ? "done" : "todo"}: ${r.objective}`);
}
console.log(`${findings.length} findings`);
```

## startTargetedPentestAgent

**`Signature`**

```ts title="Signature"
function startTargetedPentestAgent(input: PentestAgentInput): TargetedPentestHandle;
```

Takes the same input as `runTargetedPentestAgent`, but returns right away with a handle. Use it when your host needs to force teardown, such as a worker that's shutting down.

**`Import`**

```ts title="Import"
import { startTargetedPentestAgent } from "@pensar/apex/api/targetedPentest";
```

**`result`** `Promise<TargetedPentestResult>`

Settles with the same result as `runTargetedPentestAgent`. It can settle before background cleanup finishes.

---

**`drained`** `Promise<void>`

Settles when background cleanup (browser disconnect, span teardown) is complete.

---

**`abortAndDrain`** `() => Promise<void>`

Aborts the run, force-disconnects its browser, and waits for cleanup. Idempotent, and never throws.

---

```ts
const handle = startTargetedPentestAgent({ target, objectives, session, model });
process.once("SIGTERM", () => void handle.abortAndDrain());

const result = await handle.result;
await handle.drained;
```

## Related

#### [runPentestAgent](/apex/sdk/reference/run-pentest-agent)

Discover the attack surface first, then test every endpoint

#### [pensar targeted-pentest](/apex/cli-commands/pensar-targeted-pentest)

The CLI equivalent