---
id: object/codeunit/3307
type: object
title: Codeunit 3307 "Payables Agent Setup"
summary: Codeunit 3307 "Payables Agent Setup" in PayablesAgent (Microsoft.Agent.PayablesAgent). 32 public procedures, 1 event subscribers. Introduced in BC29, still in BC30.
tier: official
language: en
tags:
  - codeunit
  - payablesagent
versions:
  introduced: "29"
  last_changed: null
  deprecated: null
review:
  state: derived
  by: null
  at: null
  flags: []
generated:
  at: "2026-10-11T00:31:51.816Z"
  pipeline: 0.2.0
  prompts: {}
  input_hash: e3c9f4c42a9db3b78465046259f3f77a04c288021a7a189353b06d2ee17ea4c1
evidence:
  - kind: code
    url: https://github.com/microsoft/BCApps/blob/ea08af5ef2d6a9b5c5af4a029288abbe2c883220/src/Apps/W1/PayablesAgent/app/Setup/PayablesAgentSetup.Codeunit.al
    title: src/Apps/W1/PayablesAgent/app/Setup/PayablesAgentSetup.Codeunit.al (releases/29.x)
    date: null
    commit: ea08af5ef2d6a9b5c5af4a029288abbe2c883220
    t: null
    quote: null
links:
  learn: []
  objects: []
  features: []
  topics: []
  localizations: []
  videos: []
  posts: []
  guidelines: []
  changes:
    - change/bcapps/12256
    - change/bcapps/11484
    - change/bcapps/10515
    - change/bcapps/10253
    - change/bcapps/7546
    - change/bcapps/9805
object_type: codeunit
object_id: 3307
name: Payables Agent Setup
namespace: Microsoft.Agent.PayablesAgent
app: PayablesAgent
extends: null
first_version: "29"
last_version: "30"
present_in:
  - "29"
  - "30"
changed_in: []
source_major: "29"
obsolete: null
countries: []
ms_search_form_ids: []
counts:
  fields: 0
  procedures: 41
  events: 0
  subscribers: 1
relations:
  out: 0
  referenced_by: 0
  pages: 0
  extended_by: 0
  event_subscribers: 0
  calls: 15
  called_by: 9
  implements: 0
---

# Codeunit 3307 "Payables Agent Setup"

> Codeunit 3307 "Payables Agent Setup" in PayablesAgent (Microsoft.Agent.PayablesAgent). 32 public procedures, 1 event subscribers. Introduced in BC29, still in BC30.

PayablesAgent · Microsoft.Agent.PayablesAgent · BC29-30 · [source at ea08af5e](https://github.com/microsoft/BCApps/blob/ea08af5ef2d6a9b5c5af4a029288abbe2c883220/src/Apps/W1/PayablesAgent/app/Setup/PayablesAgentSetup.Codeunit.al) · facts from BC29

## Properties

| Property | Value |
|---|---|
| Access | Internal |
| Permissions | tabledata "Outlook Setup" = rim, tabledata "Payables Agent Setup" = rmid, tabledata "PA Known Sender" = r |

## Event subscriptions

- HandleOnAfterCreatedNewCompanyByCopyCompany subscribes to Report "Copy Company" OnAfterCreatedNewCompanyByCopyCompany

## Procedures

- `LoadSetupConfiguration(var PASetupConfiguration: Codeunit "PA Setup Configuration")`: Retrieves all the records containing setup information for the payables agent.
- `ApplyPayablesAgentSetup(var PASetupConfiguration: Codeunit "PA Setup Configuration")`: Persist the payables agent setup configured across the different records and applies the necessary actions like activating and monitoring mailboxes. This is executed both when activating and deactivating the agent.
- `GetOrCreateAgentEDocumentService(): Record "E-Document Service"`
- `WasEDocumentCreatedByAgent(EDocument: Record "E-Document"): Boolean`
- `GetAgent(var Agent: Record Agent): Boolean`: Retrieves the agent record if configured in the database, and ensures that the Payables Agent setup record is updated with the correct user security id.
- `GetAgent(var Agent: Record Agent; UpdateSetup: Boolean): Boolean`: Retrieves the agent record if configured in the database, and optionally ensures that the Payables Agent setup record is updated with the correct user security id.
- `SetAgentInstructions(AgentUserSecurityId: Guid)` (internal)
- `IsAgentDrivenLineMatchingEnabled(): Boolean` (internal): Feature-specific resolver for the agent-driven line-matching experiment, used to select the prompt variant.
- `EnsureAgentInstructionsMatchConfiguration(AgentUserSecurityId: Guid)` (internal): Reconciles the agent's persisted instructions with the current experiment configuration. The agent instructions are set once (at creation/upgrade), but tenant-level ECS experiments can change independently; this reapplies the instructions when the configuration that produced them has drifted. Cheap ...
- `TryEnsureAgentInstructionsMatchConfiguration(AgentUserSecurityId: Guid)` (internal): Non-throwing wrapper around EnsureAgentInstructionsMatchConfiguration for callers on a critical path (e.g. the e-document import event subscriber) where an instruction-refresh failure must not abort the host operation. Returns false on failure so the caller can log and continue with existing instruc...
- `GetInstructionsConfigHash(): Text` (internal): Fingerprint of every tenant-level experiment configuration that influences the agent's instructions. Generic on purpose: a future prompt-affecting experiment only needs its key added to GetInstructionsExperimentKeys (and its value consumed in prompt selection) — no new setup field required.
- `CanShowAgentActions(): Boolean` (internal)
- `InsertAccessControlForEligibleUsers(AgentUserSecurityId: Guid)` (internal)
- `AllowCreateNewAgent(): Boolean` (internal): Returns true if a new Payables Agent can be created. Blocked if an agent already exists. Otherwise allowed for SUPER users or any user who has created a posted purchase invoice.
- `AgentUserName(): Code[50]` (internal)
- `AgentDisplayName(): Text[80]` (internal)
- `AgentSummary(): Text` (internal)
- `EnsureAgentActivated(var AlreadyActivated: Boolean)` (internal): Ensures the agent is activated. If the agent does not exist, it is activated silently with trial mode initialized if eligible. Email monitoring is not enabled.
- `GetDefaultProfile(var TempAllProfile: Record "All Profile" temporary)` (internal)
- `GetDefaultAccessControls(var TempAccessControlBuffer: Record "Access Control Buffer" temporary)` (internal)
- `FeatureName(): Text` (internal)
- `HasUserCreatedPostedPurchInvoice(): Boolean` (internal): Computes is the session user has created a purchase invoice in the past 30 days. This is used as a heuristic to determine if the user should be allowed to setup the agent.
- `GetUsersThatHaveCreatedPostedPurchInvoice(): List of [Guid]` (internal): Returns the list of user security IDs that have created posted purchase invoices in the past 30 days. This is used as a heuristic to determine which users should be given access to the agent.
- `ImportInvoiceFile(FileName: Text; InStream: InStream)`: Creates an E-Document from an uploaded invoice file and triggers agent processing.
- `ShouldRequestReview(EDocument: Record "E-Document"): Boolean`: Decides whether an incoming e-document's agent task must be reviewed by a human, based on the configured review policy, the monitored folder, sender authentication (compauth / internal), and the known-senders list.
- `IsSenderRejected(EDocument: Record "E-Document"): Boolean`: Returns true when the sender of the e-document is configured with the Reject policy, meaning no agent task should be created for it.
- `IsSenderAuthenticated(EDocument: Record "E-Document"): Boolean`: Returns true when the sender of the e-document's source email can be trusted as authenticated: either composite authentication passed (compauth=pass), or the message originated inside the organization (see IsSenderInternal). Missing email or headers yields false.
- `IsSenderInternal(EDocument: Record "E-Document"): Boolean`: Returns true when the e-document's source email was stamped by Exchange as originating inside the organization (X-MS-Exchange-Organization-AuthAs = Internal). This covers intra-tenant mail (e.g. same onmicrosoft.com domain), which is not stamped with compauth. Exchange re-stamps this header on inbou...
- `CompAuthPassed(AuthenticationResults: Text): Boolean`: Returns true when an Authentication-Results header value indicates compauth=pass.
- `ClassifyKnownSendersUnusedByChange(NewPolicy: Enum "PA Email Review Policy"; NewMonitoredFolder: Text; var KnownSendersCount: Integer): Enum "PA Setup Change Impact"`: Classifies whether a pending setup change would leave the known-senders list unused. Returns None when nothing curated would be ignored (including when the list is empty).
- `ClassifyKnownSendersUnusedReason(SavedPolicy: Enum "PA Email Review Policy"; SavedMonitoredFolder: Text): Enum "PA Setup Change Impact"`: Classifies why the known-senders list is currently unused in a saved setup, regardless of whether the list has entries. Used by the Known Senders page to surface a notification.
- `PolicyLabel(Policy: Enum "PA Email Review Policy"): Text`: Returns the user-facing label for an "Email Review Policy" value, for interpolation into messages.

Plus 8 local procedures.

## Calls

From the extracted call graph of BC29 (graphify-al on the snapshot checkout): calls whose target is known from a declared type or an `Object::"Name"` argument. Interface dispatch and calls through events are not counted, so the list is not complete.

- [Codeunit 3304 "PA Setup Configuration"](../codeunit/3304.md) (20 calls: `ApplyAgentSetup → GetAgentSetupBuffer`, `ApplyEDocumentServiceSetup → GetAgentSetupBuffer`, `ApplyEDocumentServiceSetup → GetPayablesAgentSetup`, …)
- [Codeunit 152 "User Permissions"](../codeunit/152.md) (3 calls: `ApplyAgentSetup → AssignPermissionSets`, `ApplyAgentSetup → HasUserPermissionSetAssigned`, `ApplyAgentSetup → IsSuper`)
- [Codeunit 3310 "PA Validate Setup"](../codeunit/3310.md) (2 calls: `ApplyPayablesAgentSetup → (object)`, `ApplyPayablesAgentSetup → SetOutlookSetup`)
- [Codeunit 3318 "PA Trial"](../codeunit/3318.md) (2 calls: `InitializeTrialIfEligible → IsEligibleToStart`, `InitializeTrialIfEligible → StartTrial`)
- [Codeunit 4321 "Agent"](../codeunit/4321.md) (2 calls: `ApplyAgentInstructions → SetInstructions`, `GetDefaultProfile → PopulateDefaultProfile`)
- [Codeunit 4324 "Agent Setup"](../codeunit/4324.md) (2 calls: `ApplyAgentSetup → SaveChanges`, `LoadSetupConfiguration → GetSetupRecord`)
- [Codeunit 7773 "Copilot Capability"](../codeunit/7773.md) (2 calls: `AllowCreateNewAgent → IsCapabilityActive`, `CanShowAgentActions → IsCapabilityActive`)
- [Codeunit 8347 "Feature Configuration"](../codeunit/8347.md) (2 calls: `GetInstructionsConfigHash → GetConfiguration`, `IsAgentDrivenLineMatchingEnabled → GetConfiguration`)
- [Codeunit 8904 "Email Message"](../codeunit/8904.md) (2 calls: `TryGetSourceEmailHeader → Get`, `TryGetSourceEmailHeader → GetHeader`)
- [Codeunit 9024 "Azure AD Graph User"](../codeunit/9024.md) (2 calls: `ApplyPayablesAgentSetup → IsUserDelegatedAdmin`, `ApplyPayablesAgentSetup → IsUserDelegatedHelpdesk`)
- [Codeunit 1266 "Cryptography Management"](../codeunit/1266.md) (1 call: `GetInstructionsConfigHash → GenerateHash`)
- [Codeunit 2200 "Azure Key Vault"](../codeunit/2200.md) (1 call: `ApplyAgentInstructions → GetAzureKeyVaultSecret`)
- [Codeunit 3309 "PA Demo Guide"](../codeunit/3309.md) (1 call: `ApplyPayablesAgentSetup → SendDemoEmail`)
- [Codeunit 4317 "Agent System Permissions"](../codeunit/4317.md) (1 call: `AllowCreateNewAgent → CurrentUserHasCanManageAllAgentsPermission`)
- [Codeunit 457 "Environment Information"](../codeunit/457.md) (1 call: `ApplyPayablesAgentSetup → IsSaaS`)

## Called by

- [Codeunit 3303 "Payables Agent"](../codeunit/3303.md) (7 calls: `BuildAgentTask → ShouldRequestReview`, `CreateAgentTask → FeatureName`, `CreateAgentTask → GetAgent`, …)
- [Page 3304 "Payables Agent Setup"](../page/3304.md) (5 calls: `ApplySetup → ApplyPayablesAgentSetup`, `ConfirmPendingChanges → ClassifyKnownSendersUnusedByChange`, `ConfirmPendingChanges → PolicyLabel`, …)
- [Page extension 3309 "PA Purchase Invoice List"](../pageextension/3309.md) (5 calls: `OnOpenPage → CanShowAgentActions`, `ShowTaskPaneForLatestAgentTask → GetAgent`, `UploadInvoiceWithAgent → CanShowAgentActions`, …)
- [Codeunit 3316 "PA Events"](../codeunit/3316.md) (3 calls: `RecordKnownSenderOnAgentProcessingStep → WasEDocumentCreatedByAgent`, `TrackFinalizedEDocuments → WasEDocumentCreatedByAgent`, `UpdateAgentTaskTitleOnPurchaseDocumentDraftCreated → WasEDocumentCreatedByAgent`)
- [Codeunit 3305 "Payables Agent Upgrade"](../codeunit/3305.md) (2 calls: `AlwaysUpdateAgentInformationOnUpgrade → GetAgent`, `AlwaysUpdateAgentInformationOnUpgrade → SetAgentInstructions`)
- [Page 3313 "PA Known Senders"](../page/3313.md) (2 calls: `OnOpenPage → ClassifyKnownSendersUnusedReason`, `OnOpenPage → PolicyLabel`)
- [Page extension 3305 "AgentTaskList"](../pageextension/3305.md) (2 calls: `CreatePATask → LoadSetupConfiguration`, `OnOpenPage → CanShowAgentActions`)
- [Codeunit 3317 "Payables Agent OCV"](../codeunit/3317.md) (1 call: `HasProcessedEnoughDocumentsForFeedback → GetAgent`)
- [Page 3307 "PA Demo Guide"](../page/3307.md) (1 call: `OnOpenPage → LoadSetupConfiguration`)

## Recent changes

- 2026-10-05 [#12256 [Payables Agent] Exclude agent accounts from eligible users](../../changes/bcapps/12256.md) (main, BC30, fix)
- 2026-09-29 [#11484 [E-Documents Core] - Supported type direction configuration](../../changes/bcapps/11484.md) (main, BC30, feature)
- 2026-08-27 [#10515 [Payables Agent] Fix stale Payables Agent setup save](../../changes/bcapps/10515.md) (main, BC30, fix)
- 2026-08-19 [#10253 Avoid starting a write transaction under `ShowCanCreateAgent`](../../changes/bcapps/10253.md) (main, BC30, fix)
- 2026-08-18 [#7546 [Payables Agent] Agent-driven line matching](../../changes/bcapps/7546.md) (main, BC30, feature)
- 2026-07-30 [#9805 Update Email Folder tooltip to reference renamed 'Manage per sender' review option](../../changes/bcapps/9805.md) (main, BC30, fix)

## Across versions

- Present in: BC29-30
- Changed (declaration) in: none

Source: AL metadata extracted from the code (names, ids, signatures, properties); no code bodies (D10).

## Ask your agent

Procedure bodies are not stored here (D10). The call sections above are our own, per object, from the BC29 call graph. For a procedure body or the calls of one procedure, ask bc-code-atlas (external, by Stefan Maron, MIT; default corpus w1-28), which the bc-observatory plugin connects: `bcatlas_resolve_node(object_type: "codeunit", object_name: "Payables Agent Setup")`, then `bcatlas_get_procedure_body` or `bcatlas_get_neighbors` on the returned id.
