---
title: Integrations
section: features
updated: '2026-09-14'
summary: 'Connect your own CRM to cockpit. Customers stay in step with it, invoices and subscriptions are read from it, and call-recording consents are signed through it.'
---

> An **integration** is the connection between cockpit and your own CRM. One active connection per CRM type, owned by you: cockpit reads and writes records in your instance and never changes how it is set up.

## Overview

Integrations live under **Management → Integrations** and need the *manage partner integrations* permission, so an Admin can connect a CRM and a Manager cannot see the page at all. The credentials belong to your instance, which is why there is no read-only view of them.

Connecting a CRM changes three places in the portal:

- [Customers](partner_customers.md) syncs with it, links each customer to its record over there, and reads invoices and subscriptions live.
- The call-recording consent on each [PBX](partner_pbxes.md) is issued, signed and stored through your CRM's own signature module.
- **Management → CRM sync history** records what each sync run did.

Until one is connected, those pages say so and point here. Call recording and the AI features are the exception: a consent is issued and signed through your CRM, so without one there is nothing to sign and nothing to wait for - those settings behave as they always did, on each PBX's **Call recordings and AI** tab. Connect a CRM and the consent step appears.

## What it does

**Test connection** authenticates against the instance and reports back before you save, so a typo in the URL or a revoked key is caught here rather than by a failing sync later.

The API key is stored encrypted and is never sent back to the browser as ciphertext. Leaving the field blank on an edit keeps the key you already stored, so you can correct a URL or a login without re-entering it.

Only one integration of a type can be active at a time. Add a second and cockpit will refuse it while the first is still active, because "which instance is this partner's?" has to have one answer.

## Odoo

Odoo 19 or newer, with these apps installed in your instance:

- **Contacts** — customers are `res.partner` records with a customer rank.
- **Invoicing** — the invoice figures on the customers list and the invoices page.
- **Sign** — the call-recording consent. Without it the consent panel still lets you import a document you already hold.
- **Subscriptions** — optional; the subscription column is simply empty without it.

Cockpit reads and writes **records** in your instance. It never creates or alters fields, models or automations, and it uploads the consent template once, recognising it again by name.

## See also

- [Customers](partner_customers.md) - what the connection is mostly for.
- [PBXs](partner_pbxes.md) - the call-recording consent that opens the AI features.

```yaml fields
name:
  label: Name
  tab: General
  hint: 'Your own name for this connection. Shown on the integrations list and in the empty states that point here.'
type:
  label: CRM
  tab: General
  hint: 'Which CRM this connects to. Odoo today; the field exists because the provider layer behind it is not Odoo-specific.'
serverUrl:
  label: 'Server URL'
  tab: General
  hint: 'The full address of your instance, including https://. Rejected without a scheme, because every record link is built from it.'
dbName:
  label: Database
  tab: General
  hint: 'The database name inside your instance. An Odoo server can host several.'
login:
  label: Login
  tab: General
  hint: 'The user cockpit authenticates as. Whatever that user may read and write in your CRM is exactly what cockpit can do.'
apiKey:
  label: 'API key'
  tab: General
  hint: 'Stored encrypted and never sent back as ciphertext. Use the eye to reveal it; clearing the field keeps the stored key.'
is_active:
  label: Active
  tab: General
  hint: 'Only one integration of a CRM type can be active at a time, so that "which instance is this partner''s?" has one answer.'
```
