> ## Documentation Index
> Fetch the complete documentation index at: https://control-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Approve native accounting write-back

> Turn on native write-back to Procountor or Netvisor, review AI-proposed journals, and approve or reject them before Control posts anything.

export const ControlAppLink = ({path, breadcrumb, children}) => {
  const link = <a href={`https://app.control.dev${path}`} target="_blank" rel="noopener noreferrer" aria-label={breadcrumb ? `Open ${breadcrumb} in Control` : undefined}>
      {children}
    </a>;
  return breadcrumb ? <Tooltip tip={breadcrumb}>{link}</Tooltip> : link;
};

Native accounting write-back lets AI agents propose journal drafts for a Procountor or Netvisor entity. Nothing reaches
the accounting system until an Owner or Admin approves the proposal. Read/sync credentials are never used for the
write; you configure a separate credential that can be revoked independently.

Native write-back is off by default. An organization Owner enables it by configuring a write credential per
integration.

## Who can do what

| Action                                                      | Required role                               |
| ----------------------------------------------------------- | ------------------------------------------- |
| Propose a journal (`propose_native_journal_write` MCP tool) | Any user or agent with an MCP write session |
| Configure or revoke the write credential                    | Owner or Admin                              |
| Approve, reject, or reconcile a proposal                    | Owner or Admin, and not the requester       |

By default, the requester of a proposal cannot approve it. A second Owner or Admin must approve the exact proposal.

## Configure the write credential

The write credential is stored separately from the read/sync credential used by the accounting integration. Rotating
or revoking one does not affect the other.

1. Open <ControlAppLink path="/settings#agent-integrations" breadcrumb="Settings → AI and automation → Native accounting write-back"><strong>Native accounting write-back</strong></ControlAppLink>.
2. Choose the Procountor or Netvisor integration.
3. Enter the write credentials:
   * **Procountor** requires client ID, client secret, and API key for a machine user with write access to journal
     receipts.
   * **Netvisor** requires customer ID, customer key, partner ID, partner key, and the company organization ID for
     an API identifier with write access to `accounting.nv`.
4. Save. The card shows a truncated credential fingerprint so you can confirm rotation later.

Revoke the write credential at any time from the same card. Revocation blocks new proposals and pending approvals for
that integration until a new credential is configured.

<Warning>
  Do not reuse Control's read/sync credential for write-back. Create a dedicated machine user or API identifier with
  the minimum rights required to create an unfinished journal.
</Warning>

## Propose a journal from an AI agent

An MCP client with a write session calls the `propose_native_journal_write` tool. The tool never contacts Procountor
or Netvisor; it stores an immutable, hash-bound proposal that an Owner or Admin must approve.

```json theme={null}
{
  "integrationId": "int_01hxyz...",
  "receiptDate": "2026-08-31",
  "description": "August payroll accrual",
  "voucherClass": "Muistiotositteet",
  "vatType": "purchase",
  "vatStatus": 0,
  "lines": [
    { "account": "2939", "amount": -12500.0, "vatPercent": 0 },
    { "account": "5000", "amount": 12500.0, "vatPercent": 0 }
  ],
  "idempotencyKey": "payroll-accrual-2026-08"
}
```

Rules the proposal must satisfy:

* The `integrationId` must belong to a Procountor or Netvisor entity that has a configured write credential.
* Every `account` must exist in the entity's chart of accounts. Unknown accounts are rejected with
  `NATIVE_WRITE_ACCOUNT_NOT_FOUND`.
* Debits and credits must balance (within 0.005). For Procountor the balance check includes VAT.
* The journal must have between 2 and 200 lines.
* `receiptDate` must be after the last month closed in the source accounting system. Closed periods are rejected with
  `NATIVE_WRITE_PERIOD_CLOSED`.
* For Netvisor, `voucherClass` is required and must match a voucher class configured in the company.
* Reusing an `idempotencyKey` with the same payload returns the existing proposal. Reusing it with a different
  payload is rejected.

Procountor dimensions are not yet enabled. Netvisor dimensions are accepted, but unknown dimensions are rejected by
the provider instead of being created automatically.

## Review, approve, or reject a proposal

Open <ControlAppLink path="/settings#agent-integrations" breadcrumb="Settings → AI and automation → Native accounting write-back"><strong>Native accounting write-back</strong></ControlAppLink>
to see proposals. Each row shows the requester, the target integration, the journal lines, and the SHA-256 proposal
hash the approval will be bound to.

1. Review the journal lines and description against the requester's intent.
2. Compare the displayed proposal hash to the one the agent received. A hash mismatch means the proposal changed after
   review and cannot be approved without a fresh review.
3. Choose **Approve** to post the journal, or **Reject** to close the proposal without executing it. Approval is
   allowed only for Owner and Admin users other than the requester.

On approval, Control uses the separate write credential to post the journal. The provider write is scoped:

* Procountor journals are created with status `UNFINISHED`. Control does not send, edit, invalidate, or approve
  journals in Procountor.
* Netvisor vouchers are created through the `accounting.nv` resource as unchecked entries. Control does not check,
  post, or invalidate vouchers in Netvisor.

Control does not retry a failed provider call automatically.

## Reconcile a delivery-uncertain result

If the network call times out or the provider returns an unreadable receipt, the proposal moves to **Delivery
uncertain**. Control does not know whether the accounting record was created, so it does not retry.

1. Open the accounting system and search for the record using the description, date, and amounts from the proposal.
2. Return to Control and open **Reconcile** on the proposal.
3. Select **Succeeded** and enter the provider record ID when you confirm the record exists, or **Failed** when it
   does not.
4. Enter a note describing what you verified (up to 2,000 characters).
5. Save.

Reconciliation is manual only. Reconciling a proposal as failed does not queue a new attempt; propose a new journal
with a new idempotency key when needed.

## Proposal statuses

| Status             | Meaning                                                                                  |
| ------------------ | ---------------------------------------------------------------------------------------- |
| Awaiting approval  | Waiting for an Owner or Admin (other than the requester) to approve or reject.           |
| Executing          | Approved and being sent to the accounting system.                                        |
| Succeeded          | The accounting system returned a confirmed record identifier.                            |
| Failed             | The accounting system rejected the request. No record was created.                       |
| Delivery uncertain | Control did not receive a conclusive receipt. Reconcile manually before proposing again. |
| Rejected           | An Owner or Admin rejected the proposal without executing it.                            |

## Related content

* [Connect Procountor](/product-docs/integrations/procountor)
* [Connect Netvisor](/product-docs/integrations/netvisor)
* [Track closed accounting periods](/product-docs/integrations/closed-periods)
* [Connect an AI client with MCP](/product-docs/ai/mcp-server)
