> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chift.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Exact Online

export const OverviewLegend = ({showTitle = true}) => <blockquote>
    {showTitle && <p>
        <strong>Overview legend 🧭</strong>
      </p>}
    <table>
      <thead>
        <tr>
          <th>Column</th>
          <th>Value</th>
          <th>Meaning</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Geography</td>
          <td>🇫🇷 FR · 🇧🇪 BE · …</td>
          <td>Countries where the connector is officially supported.</td>
        </tr>
        <tr>
          <td rowSpan={3}>Software type</td>
          <td>SaaS</td>
          <td>Through API.</td>
        </tr>
        <tr>
          <td>On-premise (local agent)</td>
          <td>
            Software running locally — installation of a local agent is
            required.
          </td>
        </tr>
        <tr>
          <td>On-premise (API)</td>
          <td>Software running locally — API available.</td>
        </tr>
        <tr>
          <td rowSpan={2}>Status</td>
          <td>🔵 Live</td>
          <td>Connector is generally available and production-ready.</td>
        </tr>
        <tr>
          <td>🟣 Beta</td>
          <td>
            Connector is in beta — usable in production but may still evolve.
          </td>
        </tr>
        <tr>
          <td>Multi folder</td>
          <td>✅ Yes / ❌ No</td>
          <td>
            Connection to multiple accounting folders at the same time (see{' '}
            <a href="/developer-guides/api-guides/accounting/folders">
              accounting folders guide
            </a>
            ).
          </td>
        </tr>
        <tr>
          <td>Rate limits</td>
          <td>✅ No / ❌ Yes</td>
          <td>Whether the target software sets rate limits on API calls.</td>
        </tr>
        <tr>
          <td rowSpan={3}>API keys</td>
          <td>❎ No</td>
          <td>
            No API keys required (OAuth2 client secret and client ID). No
            requirements to activate the connector — you can create a
            connection.
          </td>
        </tr>
        <tr>
          <td>🔑</td>
          <td>
            Keys are required to activate the connector. Chift cannot act as
            intermediary to obtain them; we can still assist with steps to get
            keys directly from the software provider.
          </td>
        </tr>
        <tr>
          <td>🔑 ☑️ via Chift</td>
          <td>
            Keys are required to activate the connector. You can go through
            Chift to get the keys (intermediary or partnership keys). An
            approval process may still apply, but you do not need to request
            keys from the vendor on your own.
          </td>
        </tr>
        <tr>
          <td rowSpan={3}>Approval / certification process</td>
          <td>⚡ Instant</td>
          <td>
            No keys required, or Chift can encode their keys for you when
            requested. Activation is instantaneous.
          </td>
        </tr>
        <tr>
          <td>🟢 Approval — [Duration]</td>
          <td>
            Approval will be granted. The vendor may require information or app
            configuration in a developer portal before issuing keys.
          </td>
        </tr>
        <tr>
          <td>🟠 Approval — [Duration]</td>
          <td>
            Approval is not guaranteed — often due to integration strategy; the
            vendor may do a deeper assessment (competitors, partnership
            requirements, and similar).
          </td>
        </tr>
        <tr>
          <td rowSpan={2}>Activation time</td>
          <td>⚡ Instant</td>
          <td>
            If no keys are required, or Chift has keys ready to share with you.
          </td>
        </tr>
        <tr>
          <td>Time</td>
          <td>
            Estimated time to get the connector activated in production as a
            result of the approval or certification process (e.g. ⏱️ 2 days, 1
            week).
          </td>
        </tr>
        <tr>
          <td rowSpan={3}>Extra fees — software editor</td>
          <td>❎ No</td>
          <td>No fees charged by the software editor.</td>
        </tr>
        <tr>
          <td>💰 🕹️</td>
          <td>Fees associated with obtaining a testing account.</td>
        </tr>
        <tr>
          <td>💰 🔑</td>
          <td>Fees charged to get API keys.</td>
        </tr>
        <tr>
          <td rowSpan={2}>Extra fees — end user</td>
          <td>❎ No</td>
          <td>The end user does not pay extra to get integrated.</td>
        </tr>
        <tr>
          <td>💰 Yes</td>
          <td>The end user must pay extra to get integrated.</td>
        </tr>
        <tr>
          <td>Comments on costs</td>
          <td>—</td>
          <td>Additional notes on fees or pricing when relevant.</td>
        </tr>
        <tr>
          <td rowSpan={4}>Sandbox account</td>
          <td>✅ via Chift</td>
          <td>Chift can provide you with a sandbox.</td>
        </tr>
        <tr>
          <td>🟠 Only through integrator</td>
          <td>Only the software's integrator can provide a sandbox.</td>
        </tr>
        <tr>
          <td>✅ Self-service</td>
          <td>You can create your own sandbox.</td>
        </tr>
        <tr>
          <td>✅ Trial account</td>
          <td>It is possible to create a trial account.</td>
        </tr>
      </tbody>
    </table>
  </blockquote>;

export const ConnectorCardIframe = ({api = 'accounting', connectors}) => {
  const [theme, setTheme] = React.useState('light');
  React.useEffect(() => {
    const checkTheme = () => {
      const isDark = document.documentElement.classList.contains('dark');
      setTheme(isDark ? 'dark' : 'light');
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  const queryParams = new URLSearchParams({
    api,
    theme,
    ...connectors ? {
      connectors
    } : {}
  });
  const iframeUrl = `https://chift-coverage-matrix.s3.eu-west-3.amazonaws.com/connector-card.html?${queryParams.toString()}`;
  return <iframe src={iframeUrl} title={`Chift connector information - ${api}`} style={{
    display: 'block',
    width: '100%',
    height: '480px',
    margin: 0,
    padding: 0,
    border: 'none'
  }} />;
};

export const CoverageIframe = ({api = 'accounting', connectors}) => {
  const [theme, setTheme] = React.useState('light');
  const [isFullscreen, setIsFullscreen] = React.useState(false);
  const [currentIframeUrl, setCurrentIframeUrl] = React.useState(null);
  const iframeRef = React.useRef(null);
  React.useEffect(() => {
    const checkTheme = () => {
      const isDark = document.documentElement.classList.contains('dark');
      setTheme(isDark ? 'dark' : 'light');
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  React.useEffect(() => {
    const handleFullscreenChange = () => {
      setIsFullscreen(!!document.fullscreenElement);
    };
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);
  }, []);
  React.useEffect(() => {
    const handleMessage = event => {
      if (!event.origin.includes('chift-coverage-matrix.s3.eu-west-3.amazonaws.com')) return;
      if (event.data?.type === 'urlChange' && event.data?.url) {
        setCurrentIframeUrl(event.data.url);
      }
    };
    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, []);
  const queryParams = new URLSearchParams({
    api,
    theme,
    ...connectors ? {
      connectors
    } : {}
  });
  const iframeUrl = `https://chift-coverage-matrix.s3.eu-west-3.amazonaws.com/coverage.html?${queryParams.toString()}`;
  const openUrl = currentIframeUrl || iframeUrl;
  const toggleFullscreen = () => {
    if (!document.fullscreenElement) {
      iframeRef.current?.requestFullscreen();
    } else {
      document.exitFullscreen();
    }
  };
  const isDark = theme === 'dark';
  const buttonStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    gap: '8px',
    padding: '4px 12px',
    fontSize: '14px',
    fontWeight: '500',
    color: isDark ? '#d4d4d4' : '#374151',
    backgroundColor: 'transparent',
    border: `1px solid ${isDark ? '#404040' : '#e5e7eb'}`,
    borderRadius: '12px',
    cursor: 'pointer',
    textDecoration: 'none',
    transition: 'all 0.15s ease'
  };
  const hoverBg = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)';
  const hoverBorder = isDark ? '#525252' : '#d1d5db';
  const defaultBg = 'transparent';
  const defaultBorder = isDark ? '#404040' : '#e5e7eb';
  return <>
  <div style={{
    display: 'flex',
    justifyContent: 'flex-end',
    gap: '12px',
    marginBottom: '8px'
  }}>
    <button onClick={toggleFullscreen} style={buttonStyle} onMouseEnter={e => {
    e.target.style.backgroundColor = hoverBg;
    e.target.style.borderColor = hoverBorder;
  }} onMouseLeave={e => {
    e.target.style.backgroundColor = defaultBg;
    e.target.style.borderColor = defaultBorder;
  }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        {isFullscreen ? <>
            <polyline points="4 14 10 14 10 20"></polyline>
            <polyline points="20 10 14 10 14 4"></polyline>
            <line x1="14" y1="10" x2="21" y2="3"></line>
            <line x1="3" y1="21" x2="10" y2="14"></line>
          </> : <>
            <polyline points="15 3 21 3 21 9"></polyline>
            <polyline points="9 21 3 21 3 15"></polyline>
            <line x1="21" y1="3" x2="14" y2="10"></line>
            <line x1="3" y1="21" x2="10" y2="14"></line>
          </>}
      </svg>
      {isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'}
    </button>
    <a href={iframeUrl} target="_blank" rel="noopener noreferrer" style={buttonStyle} onMouseEnter={e => {
    e.target.style.backgroundColor = hoverBg;
    e.target.style.borderColor = hoverBorder;
  }} onMouseLeave={e => {
    e.target.style.backgroundColor = defaultBg;
    e.target.style.borderColor = defaultBorder;
  }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
        <polyline points="15 3 21 3 21 9"></polyline>
        <line x1="10" y1="14" x2="21" y2="3"></line>
      </svg>
      Open in new tab
    </a>
  </div>
  <iframe ref={iframeRef} src={iframeUrl} title={`Chift Coverage Matrix - ${api}`} style={{
    height: 'max(500px, 80vh)'
  }} className="w-full" allowFullScreen />
  <blockquote>
    <p>
      <strong>Matrix Legend 🧭</strong>
    </p>
    <table>
      <thead>
        <tr>
          <th>Status</th>
          <th>Meaning</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>✅ Implemented</td>
          <td>Endpoint is implemented and available.</td>
        </tr>
        <tr>
          <td>❌ Not supported</td>
          <td>
            Endpoint is not supported by the target software (connector
            limitation). Cannot be implemented.
          </td>
        </tr>
        <tr>
          <td>💬 On request</td>
          <td>
            Endpoint is not implemented but feasibility is validated. Can be
            implemented on request — contact your Chift point of contact to
            discuss scope and timing.
          </td>
        </tr>
        <tr>
          <td>🔎 To be analyzed</td>
          <td>
            Endpoint is not implemented and feasibility has not yet been fully
            assessed. Analysis is pending.
          </td>
        </tr>
      </tbody>
    </table>
  </blockquote>
</>;
};

<ConnectorCardIframe api="accounting" connectors="Exact Online BE" />

<Accordion title="Overview Legend 🧭">
  <OverviewLegend showTitle={false} />
</Accordion>

## Introduction

Exact Online is a business software that provides a range of tools for small and medium-sized enterprises to manage their finances, accounting, inventory, and project management. Deliver the Exact integration your customer wants in no time.

## Configure Exact Online

**Prerequisite(s)** You will have to get listed as an Exact Online partner to collect partner account keys to configure the connector on your account. To do so, you will need to:

* Create an Exact Online partner account, with an OAuth2 application.
* Configure your partner account
* Submit your application for Exact Online's approval

**Activation Process**

1. Create your Exact Online developer account:     \
   [Link for a Belgium account](https://start.exactonline.be/docs/HRMSubTrialNew.aspx?bcaction=0\&type=10\&language=EN\&UseSimpleWizard=1\&PackageSetCode=APPCENTER)\
   [Link for a French account](https://start.exactonline.fr/docs/HRMSubTrialNew.aspx?bcaction=0\&type=10\&language=EN\&UseSimpleWizard=1\&PackageSetCode=APPCENTER)\
   [Link for a Dutch account](https://start.exactonline.nl/docs/HRMSubTrialNew.aspx?bcaction=0\&type=10\&language=EN\&UseSimpleWizard=1\&PackageSetCode=APPCENTER)\
   [Link for a German account](https://start.exactonline.de/docs/HRMSubTrialNew.aspx?bcaction=0\&type=10\&language=EN\&UseSimpleWizard=1\&PackageSetCode=APPCENTER)

<Warning>
  Creating a developer account for **Exact Online** now requires a **paid monthly subscription**.

  To register an application and get access to Exact Online APIs, developers must first subscribe to a **developer plan**. More info [here](https://support.exactonline.com/community/s/knowledge-base#All-All-DNO-Content-developerssubscriptiont).
</Warning>

2. Set up your Oauth2 application by going to your Exact Online account → “Partners” section in the menu → “Exact Online App Store” (In the section “Manage my applications”)
   * Create a new application by clicking on “+”
   * Enter the name of your APP to be displayed in Exact Online’s Marketplace
   * Enter the redirect URL (Chift): [https://chift.app/oauth2/redirect](https://chift.app/oauth2/redirect)
   * Make sure you tick all the below configurations of your app <img src="https://mintcdn.com/chift/eShhUiVRq1jW2mtb/assets/images/exactonline/exactonlineconfiguration.jpg?fit=max&auto=format&n=eShhUiVRq1jW2mtb&q=85&s=3f8ae5308ffeae7a1aa27bf429432335" alt="Exactonline" width="1920" height="1080" data-path="assets/images/exactonline/exactonlineconfiguration.jpg" />
3. Wait for Exact Online’s approval of your application - this may take a few days.
4. Go to your account, connectors menu and activate Exact Online in one click. Then, you will be asked to provide your Exact Online client ID & secret.

## Test Exact Online

To test the software integration, you can use the partner account you created during the configuration process.

-> Once the testing is done, you need to get the approval of Exact Online to use the integration (your app) with external clients. Once your app is approved, external clients will be able to use the integration.

## Connect Exact Online

To activate a connection with Exact Online, users will have to go through the following steps.

* For Netherlands: [Help Center - Exact Online - NL](https://help.chift.app/articles/3853865771-exact-online-nl?lang=en)
* For Belgium: [Help Center - Exact Online - BE](https://help.chift.app/articles/7719703254-exact-online-be?lang=en)
* For France: [Help Center - Exact Online - FR](https://help.chift.app/articles/8093104901-exact-online-fr?lang=fr)
* For Germany: [Help Center - Exact Online - DE](https://help.chift.app/articles/8976563324-exact-online-de?lang=en)

## Rate limits

The Exact Online API is subject to the following limits:

* **60 requests per minute**
* **5,000 requests per day**

These limits apply per Exact Online environment.

Users can increase the daily API limit by subscribing to an **Exact Online Premium** plan:

* **Up to 30,000 requests per day**
* **No per-app request limit**

Exact Online enforces a **fair use policy**. Applications that excessively exceed limits or generate abusive traffic may be throttled or blocked.

For more details, see the Exact Online documentation:\
[https://support.exactonline.com/community/s/knowledge-base#All-All-DNO-Simulation-gen-apilimits](https://support.exactonline.com/community/s/knowledge-base#All-All-DNO-Simulation-gen-apilimits)

## Technical limitations & specificities

### PDF attachments on financial entries

Exact Online does not allow attaching PDFs to entries that are not linked to a customer or supplier. If the financial entry has no associated customer/supplier, the PDF upload will be rejected.

## Coverage

<CoverageIframe api="accounting" connectors="Exact Online BE" />

## Troubleshooting

### Specific errors for Exact Online:

| Error Code                                     | Error description                                                                                          | Resolution                                                                                 |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| ERROR\_ACCOUNT\_NUMBER\_NOT\_GOOD\_SCOPE       | Only receivable/payable accounts can be used as a forced general account with partner accounts.            | Use a receivable or payable account as the forced general account.                         |
| ERROR\_ANALYTIC\_ACCOUNT\_NOT\_CONFIGURED      | Analytic accounts need to be configured correctly to be used with a specific ledger account.               | Configure the analytic account for the ledger account in Exact Online.                     |
| ERROR\_BANK\_ACCOUNT\_NUMBER\_ALREADY\_EXISTS  | Exact Online has a uniqueness constraint on bank account numbers.                                          | Use a unique bank account number.                                                          |
| ERROR\_CONNECTOR\_MAINTENANCE                  | Exact Online is performing maintenance (usually around 4AM).                                               | Retry the request after the maintenance window.                                            |
| ERROR\_INVALID\_FIELD\_FORMAT\_BANK\_ACCOUNT   | The bank account or IBAN is not valid.                                                                     | Provide a valid bank account number or IBAN.                                               |
| ERROR\_INVALID\_FIELD\_FORMAT\_INVOICE\_NUMBER | The invoice number can only contain numbers between 1 and 4294967295.                                      | Use a valid numeric invoice number within the allowed range.                               |
| ERROR\_INVALID\_FIELD\_FORMAT\_NUMBER          | The entry number must be between 1 and 4294967295.                                                         | Use a valid numeric entry number within the allowed range.                                 |
| ERROR\_INVALID\_BODY                           | An attachment can only be linked to an entry when a client or supplier account is used in the entry items. | Include a client or supplier account in the entry items before attaching a PDF.            |
| ERROR\_NO\_GL\_ACCOUNT\_CODE\_FOUND            | Could not determine the account number linked to the created bank account.                                 | Verify the bank account configuration in Exact Online.                                     |
| ERROR\_PARTNER\_ALREADY\_EXISTS                | Exact Online found a duplicate client or supplier based on uniqueness checks (e.g., VAT number).           | Check for existing clients/suppliers with the same VAT number or other unique identifiers. |
