# PCAOB Form AP Auditor Lookup — Engagement Partner Tenure (`malekh/pcaob-form-ap-auditor-lookup`) Actor

Look up any SEC issuer's audit firm and named engagement partner from PCAOB Form AP. Returns the full engagement history by fiscal year, computed partner tenure against the five-year lead-partner rotation limit, and auditor and partner change events. Superseded amendments excluded.

- **URL**: https://apify.com/malekh/pcaob-form-ap-auditor-lookup.md
- **Developed by:** [Malek H](https://apify.com/malekh) (community)
- **Categories:** Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## PCAOB Form AP Auditor Lookup — Engagement Partner & Tenure

Look up **who audits an SEC issuer, which named engagement partner signed it,
and how many consecutive years that partner has been signing** — straight from
**PCAOB Form AP**.

Give it a CIK. Get back the full audit engagement history by fiscal year, the
audit firm and named engagement partner for each, computed partner tenure
against the five-year lead-partner rotation limit, and every auditor and partner
change with the year it happened.

Form AP is the only public record naming the individual engagement partner on a
US issuer audit. This Actor turns it into something you can query in bulk.

### What you get

For each issuer:

| Field | What it is |
|---|---|
| `currentAuditFirms` / `currentEngagementPartners` | Who signed the most recent fiscal period |
| `rotationAssessment` | Per current partner: consecutive years signed, and where that stands against the five-year limit |
| `engagementPartnerTenure` | Every partner who has signed, with fiscal years served and longest consecutive run |
| `auditFirmTenure` | The same, per audit firm |
| `auditFirmChanges` | Auditor changes, with the fiscal year |
| `engagementPartnerChanges` | Partner changes, with the fiscal year |
| `engagements` | One entry per fiscal period: firm, firm office, partner, secondary partner, report type, fund series, report and filing dates |

### Who this is for

- **Investors and analysts** — auditor changes and unusually long partner tenure
  are classic governance screens. Run a whole portfolio in one go.
- **Audit committees and audit firms** — track lead-partner rotation across an
  issuer book instead of by hand.
- **Litigation support and forensic accountants** — establish who signed which
  audit, in which year, from the authoritative filing.
- **Academic researchers** — bulk auditor-and-partner panel data without buying
  a commercial dataset.

### Input

```json
{
  "issuers": [
    { "recordId": "P-1", "cik": "320193" },
    { "recordId": "P-2", "cik": "1318605" },
    { "recordId": "P-3", "issuerName": "3M CO" }
  ],
  "includeEngagements": true
}
```

Bare CIK strings work too: `{"issuers": ["320193", "1318605"]}`.

- **`cik`** — the SEC CIK. Leading zeros are fine (`0000320193` = `320193`).
  This is the reliable way to look an issuer up.
- **`issuerName`** — matched **exactly** after normalising case, punctuation and
  corporate suffixes (`Apple Inc.` = `APPLE INC` = `Apple`). A near miss returns
  `issuer_not_found` plus suggestions — it will never quietly answer about a
  different company, because `Apple Inc.` and `Apple Hospitality REIT, Inc.` are
  not the same issuer.
- **`recordId`** — optional, echoed back on every result so output joins to your
  own records.
- **Ticker symbols are not supported.** The ticker column in the PCAOB export is
  empty for every row, by design. Use CIK.

Up to 5,000 issuers per run. Set `includeEngagements` to `false` for a compact
result with just the computed summary.

### Sample output

```json
{
  "recordId": "P-1",
  "status": "found",
  "issuerName": "Apple Inc.",
  "issuerCik": "320193",
  "latestFiscalPeriodEnd": "2025-09-27",
  "currentAuditFirms": ["Ernst & Young LLP"],
  "currentEngagementPartners": ["Craig Ralph Smith Jr."],
  "partnerRotationFlagged": false,
  "rotationAssessment": [
    {
      "partnerName": "Craig Ralph Smith Jr.",
      "consecutiveFiscalYears": 2,
      "firstFiscalYear": 2024,
      "rotationStatus": "within_limit",
      "tenureIsLowerBound": false
    }
  ],
  "engagementPartnerChanges": [
    { "fiscalYear": 2019, "from": ["Patrick Allen Hyek"], "to": ["Kevin Frank Asher"] },
    { "fiscalYear": 2024, "from": ["Kevin Frank Asher"], "to": ["Craig Ralph Smith Jr."] }
  ],
  "sourceAsOf": "2026-07-28"
}
```

### Partner rotation — read this before acting on it

SEC Regulation S-X Rule 2-01(c)(6) requires the **lead engagement partner to
rotate off after five consecutive years**. Form AP names that partner, so tenure
is computable — but the public record has limits, and this Actor states them
instead of papering over them.

`rotationStatus` is one of:

- **`within_limit`** — under five consecutive years, and the partner first
  appears *after* Form AP coverage begins for this issuer, so the count is
  complete.
- **`approaching_limit`** — four consecutive years, complete count.
- **`at_or_beyond_limit`** — five or more consecutive years. **This is a prompt
  to look, not a finding of non-compliance.** Rule 2-01(c)(6)(ii) exempts firms
  with fewer than five issuer audit clients and fewer than ten partners, and
  firm size is not in Form AP, so it cannot be ruled out here.
- **`indeterminate`** — the partner was already signing in the issuer's first
  covered year. Years served before Form AP existed are not public, so actual
  tenure may already exceed the limit. Reported as unresolved, never as
  compliant.
- **`not_assessed`** — the engagement is an employee benefit plan or investment
  company audit. The five-year lead-partner limit is an issuer-audit rule, so
  tenure is given without a verdict rather than judged by a rule that may not
  govern it.

**All tenure figures are a floor, not a total.** Form AP covers audit reports
issued from 2017 onward; `formApCoverageFromFiscalYear` and
`firstFiscalYearCovered` are on every record so you can see exactly how far back
the evidence goes.

### Data source and correctness

Source: the PCAOB Form AP firm-filings bulk export,
`https://assets.pcaobus.org/firm-filings/FirmFilings.zip` — 155,241 filings,
regenerated daily by the PCAOB. Public, keyless, no scraping.

A lookup tool that quietly returns "nothing found" when its source breaks is
worse than one that crashes, so this Actor **fails the run rather than reporting
a clean answer it cannot stand behind**. It aborts if the export is truncated,
if a required column is renamed or reordered, if the amendment flag disappears,
or if the newest filing is more than 30 days old (the PCAOB refreshes daily; the
largest gap ever observed in the file is three days).

Three details are handled that a naive read of this file gets wrong:

1. **Superseded amendments.** An amended Form AP leaves the original in the
   export flagged `Latest Form AP Filing = 0`. Counting those would duplicate
   fiscal years and inflate partner tenure. Only current filings are read.
2. **Legitimate duplicate filings.** Even among current filings, one issuer and
   fiscal period can carry two entries — a separate filing for a dual-dated or
   multiple-period report, which is *not* marked as an amendment. Those are
   deduplicated; a genuinely different firm or partner in the same year survives
   as the distinct engagement it is.
3. **Back-filed outliers.** A handful of rows carry mistyped fiscal periods
   reaching back to 1919. Coverage is reported from the earliest year holding a
   material share of filings, not from the raw minimum.

Every record carries `sourceAsOf` and `sourceRowCount` so you can see exactly
which snapshot answered you.

Verify any individual filing at
[PCAOB AuditorSearch](https://pcaobus.org/resources/auditorsearch).

### Result statuses

| `status` | Meaning |
|---|---|
| `found` | Form AP filings located for this issuer |
| `issuer_not_found` | No filings. **Not** evidence the company is unaudited — Form AP starts in 2017 and covers only PCAOB-registered firms' issuer audits. Includes name suggestions. |
| `invalid_input` | Neither a numeric CIK nor a usable issuer name was supplied |

### Pricing

Pay per event: one **lookup run** charge covering the download and the scan of
all 155,241 filings, plus a small per-**issuer checked** charge. Malformed
inputs are not charged. Platform usage costs are included.

# Actor input Schema

## `issuers` (type: `array`):

The SEC issuers to look up in PCAOB Form AP. Either bare numeric CIK strings, or objects with a 'cik' (leading zeros fine) or an 'issuerName', plus an optional 'recordId' that is echoed back on the result so rows reconcile with your own system. CIK is far more reliable: name matching is exact after normalising case, punctuation and corporate suffixes, and a near miss returns suggestions rather than guessing at a different company. Ticker symbols are NOT supported — the ticker column in the PCAOB export is empty by design. Up to 5,000 issuers per run.

## `includeEngagements` (type: `boolean`):

Include every individual Form AP engagement (one entry per fiscal period, with firm, office, engagement partner, secondary partner and fund series). Turn this off for a smaller result that keeps only the computed summary: current auditor, current engagement partner, tenure, rotation assessment and change history.

## Actor input object example

```json
{
  "issuers": [
    {
      "recordId": "P-1",
      "cik": "320193"
    },
    {
      "recordId": "P-2",
      "cik": "1318605"
    },
    {
      "recordId": "P-3",
      "issuerName": "3M CO"
    }
  ],
  "includeEngagements": true
}
```

# 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 = {
    "issuers": [
        {
            "recordId": "P-1",
            "cik": "320193"
        },
        {
            "recordId": "P-2",
            "cik": "1318605"
        },
        {
            "recordId": "P-3",
            "issuerName": "3M CO"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("malekh/pcaob-form-ap-auditor-lookup").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 = { "issuers": [
        {
            "recordId": "P-1",
            "cik": "320193",
        },
        {
            "recordId": "P-2",
            "cik": "1318605",
        },
        {
            "recordId": "P-3",
            "issuerName": "3M CO",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("malekh/pcaob-form-ap-auditor-lookup").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "issuers": [
    {
      "recordId": "P-1",
      "cik": "320193"
    },
    {
      "recordId": "P-2",
      "cik": "1318605"
    },
    {
      "recordId": "P-3",
      "issuerName": "3M CO"
    }
  ]
}' |
apify call malekh/pcaob-form-ap-auditor-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=malekh/pcaob-form-ap-auditor-lookup",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/30dyznYfIEIOcrtTu/builds/NwnibI3SjXEn5ja8d/openapi.json
