{
  "schema": "aaes/capability-pack/1",
  "provider": "pardot",
  "version": "1.0.0",
  "description": "Read Salesforce Account Engagement prospects, lists, campaigns, and visitors; add prospects to static email lists. Membership can trigger communication through an active engagement program or list-email send.",
  "notes": "The endpoint host is a real shared Account Engagement host: production and training environments are served from pi.pardot.com, and demo, developer-org and sandbox environments from pi.demo.pardot.com. This pack registers the production host; a deployment against a sandbox substitutes pi.demo.pardot.com in the endpoints, the resource locators and the egress allowlist together — the allowlist matches exactly.\n\nThere is no per-customer host placeholder here, but every request must carry the business unit in the Pardot-Business-Unit-Id header (an 18-character id beginning 0Uv, found in Salesforce Setup > Business Unit Setup): that id is configuration, not a secret, and the deployment must wire it for the executor, because a request without it fails even with a valid token.\n\nThe pack pins API version 5 deliberately: versions 3 and 4 are legacy. Version 5 reads can be served from a cache that runs up to roughly 60 seconds behind the primary data, so a read is not a real-time guarantee. Reads are registered against the query (collection) endpoints only: single-record reads (GET /api/v5/objects/prospects/<id>, /lists/<id>, /campaigns/<id>, /visitors/<id>) are not registered by this pack.\n\nApproval classification: marketing automation is send-first.\n\nCreating a list membership adds a prospect to a static email list, and Account Engagement documents lists as groups of prospects used to send list emails or to feed engagement programs — membership can initiate communication through an active program or list-email send, though membership alone does not guarantee an email is sent; once a send occurs it cannot be recalled — so the capability declares create and send, and send keeps the tier at the minimum R3 tier; send is one of the designated actions requiring human approval.\n\nDocumented exclusions — this pack does not register: prospect create, update, delete, upsert (upsertLatestByEmail) or undelete; list create, update or delete; list-membership update (including the optedOut flag, which the documentation states can be set to opt a prospect out of a list's emails but cannot be set back — a one-way change a reviewer should enable separately) and list-membership delete; visitor assignToProspect and identifyCompany; campaign connectSalesforceCampaign; engagement-studio program management (not part of the v5 object surface reviewed here); the legacy v3/v4 endpoints, including their one-off email send operations; and the Export API.\n\nCredential review completed on 2026-09-21 for a Salesforce OAuth access token held in the customer's vault and refreshed by an external process. The requirements and limits are below.\n\nIssuance authority and delegation: tokens are minted by Salesforce's authorizing server for a connected app whose selected OAuth scopes include pardot_api, for an SSO-enabled integration user (one who can log in with Salesforce or use the Account Engagement Lightning App); the Web Server Flow is the most commonly used of the supported OAuth 2.0 flows.\n\nScope: the connected app's selected scopes carry pardot_api, and the documented object abilities bound what the token may do — Prospect > Prospects > View for prospect reads, Marketing > Segmentation > Lists > View for list reads, Marketing > Other > Campaigns > View for campaign reads, Prospect > Visitors > View for visitor reads, and Marketing > Segmentation > Create with Prospect > Prospects > Create only if the list-membership capability is enabled.\n\nAudience: every request is bound to one business unit by the Pardot-Business-Unit-Id header (an 18-character id beginning 0Uv, configuration rather than credential material); beyond that binding the retrieved docs document no audience claim. TTL: the specific session/connected-app expiry policy page renders JavaScript-only and could not be retrieved, so this pack deliberately makes no numeric claim about access-token lifetime — the completed review documents this gap, and the deployment must verify the connected app's session/timeout policy against Salesforce's session-settings documentation before enabling.\n\nRefresh ownership: renewal follows the flow the connected app allows (a refresh_token flow or JWT bearer flow) and sits entirely with the external process; the executor injects the stored value verbatim and performs no token lifecycle itself.\n\nRevocation: revoke the token or the connected app's authorization in Salesforce — a Salesforce-side administrative action the retrieved pages do not contradict — and an expired or revoked value fails closed. Executor access and replay/exposure: the executor reads only the vault reference; the token is a bearer credential whose replay window is the org-configured session lifetime the deployment must verify, since no numeric TTL is established.\n\nAlternate access paths: the Salesforce and Account Engagement UIs and other connected apps retain access outside this pack, and revoking this authorization closes only this path. The credential review is complete. Assign accountable owners before deployment.",
  "credential": {
    "secret_ref_id": "secret-ref-pardot-salesforce-oauth",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "A Salesforce OAuth 2.0 access token, held in the client's own secret manager, minted by an external process from a connected app whose selected OAuth scopes include pardot_api, for an SSO-enabled integration user (one who can log in with Salesforce or use the Account Engagement Lightning App). The stored material must be the complete Authorization header value: the scheme 'Bearer', one separating space, then the token.\n\nSession and renewal policy: the retrieved Account Engagement authentication page documents the OAuth prerequisites (a connected app with the pardot_api scope, an SSO-enabled user, and the Pardot-Business-Unit-Id header) and that the Web Server Flow is the most commonly used of the supported OAuth 2.0 flows, with renewal following the flow the connected app allows (a refresh_token flow or JWT bearer flow); refresh ownership sits entirely with the external process — the executor injects the stored value verbatim and performs no token lifecycle itself.\n\nThe specific session/connected-app expiry policy page (Salesforce Help) could not be retrieved for this review — it renders JavaScript-only — so this pack deliberately makes no numeric claim about access-token lifetime: the deployment must verify the connected app's session/timeout policy against Salesforce's own session-settings documentation before enabling, and the completed custody review records that unverified lifetime as a documented finding rather than a draft blocker.\n\nEvery Account Engagement API v5 request must also carry the Pardot-Business-Unit-Id header with the target business unit's id (18 characters, beginning 0Uv); the id is configuration rather than credential material, but the deployment must wire it alongside the credential.\n\nLeast privilege, per the documented ability requirements: Prospect > Prospects > View for prospect reads, Marketing > Segmentation > Lists > View for list reads, Marketing > Other > Campaigns > View for campaign reads, Prospect > Visitors > View for visitor reads, and Marketing > Segmentation > Create with Prospect > Prospects > Create only if the list-membership capability is enabled.\n\nRevocation: revoke the token or the connected app's authorization in Salesforce; an expired or revoked value fails closed.\n\nExecutor hygiene: the value must live only in executor memory for the lifetime of a call, must never be written to logs, traces or diagnostics, and must not appear in crash dumps; a deployment that cannot meet that bar must not enable the pack."
  },
  "capabilities": [
    {
      "capability_id": "pardot.prospects.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "pi.pardot.com"
      ],
      "endpoint": "https://pi.pardot.com/api/v5/objects/prospects",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-pardot-salesforce-oauth",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "pardot-prospects",
      "description": "Query prospect records in the business unit: email addresses, names, phone numbers, scores and opt-out flags, which identify named people, so the read is classified as pii (personal data). The registered path covers the collection query only — single-prospect reads (GET /api/v5/objects/prospects/<id>) are not registered by this pack. Requires the Prospect > Prospects > View ability.",
      "requires_review": true
    },
    {
      "capability_id": "pardot.lists.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "pi.pardot.com"
      ],
      "endpoint": "https://pi.pardot.com/api/v5/objects/lists",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-pardot-salesforce-oauth",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "pardot-lists",
      "description": "Query lists in the business unit: names, descriptions and dynamic/public flags — segmentation metadata, classified as internal data. The registered path covers the collection query only — single-list reads (GET /api/v5/objects/lists/<id>) and list-membership queries are not registered by this pack. Requires the Marketing > Segmentation > Lists > View ability.",
      "requires_review": true
    },
    {
      "capability_id": "pardot.campaigns.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "pi.pardot.com"
      ],
      "endpoint": "https://pi.pardot.com/api/v5/objects/campaigns",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-pardot-salesforce-oauth",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "pardot-campaigns",
      "description": "Query campaigns in the business unit: names, folders and cost fields — marketing metadata, classified as internal data. The registered path covers the collection query only — single-campaign reads (GET /api/v5/objects/campaigns/<id>) and the connectSalesforceCampaign operation are not registered by this pack. Requires the Marketing > Other > Campaigns > View ability.",
      "requires_review": true
    },
    {
      "capability_id": "pardot.visitors.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "pi.pardot.com"
      ],
      "endpoint": "https://pi.pardot.com/api/v5/objects/visitors",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-pardot-salesforce-oauth",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "pardot-visitors",
      "description": "Query visitor records: IP addresses, hostnames, page-view counts and referring parameters for the people who interacted with tracked pages — behavioural personal data, so the read is classified as pii (personal data). The registered path covers the collection query only — single-visitor reads (GET /api/v5/objects/visitors/<id>) and the assignToProspect and identifyCompany operations are not registered by this pack. Requires the Prospect > Visitors > View ability.",
      "requires_review": true
    },
    {
      "capability_id": "pardot.list-memberships.create",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "pi.pardot.com"
      ],
      "endpoint": "https://pi.pardot.com/api/v5/objects/list-memberships",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-pardot-salesforce-oauth",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create",
        "send"
      ],
      "resource_id": "pardot-prospects",
      "description": "Create a list membership: add a named prospect to a static email list. Account Engagement documents lists as groups of prospects used to send list emails or to feed engagement programs, so membership can initiate communication through an active engagement program or a list-email send — outbound email that cannot be recalled once delivered — while membership alone does not guarantee an email is sent.\n\nThe capability therefore declares create (the membership itself) and send (the communication an active program or list send can trigger), and send keeps the tier at the minimum R3 tier; send is one of the designated actions requiring human approval.\n\nOn supported AAES-mediated execution paths, irreversible actions require approval by an authorized person; this does not prevent calls through bypass or observation-only paths. Requires the Marketing > Segmentation > Create and Prospect > Prospects > Create abilities.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "pardot-prospects",
      "kind": "api",
      "locator": "https://pi.pardot.com/api/v5/objects/prospects",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "pardot-lists",
      "kind": "api",
      "locator": "https://pi.pardot.com/api/v5/objects/lists",
      "data_class": "internal",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "pardot-campaigns",
      "kind": "api",
      "locator": "https://pi.pardot.com/api/v5/objects/campaigns",
      "data_class": "internal",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "pardot-visitors",
      "kind": "api",
      "locator": "https://pi.pardot.com/api/v5/objects/visitors",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-09-22",
    "sources": [
      "https://developer.salesforce.com/docs/marketing/pardot/guide/overview.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/version5overview.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/authentication.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/prospect-v5.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/list-v5.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/campaign-v5.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/visitor-v5.html (retrieved 2026-09-21)",
      "https://developer.salesforce.com/docs/marketing/pardot/guide/list-membership-v5.html (retrieved 2026-09-21)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
