---
title: CRM Lookup
excerpt: Recherchez et créez des contacts, journalisez les appels téléphoniques, enregistrez des contextes d'appel et poussez les sessions de chat dans votre CRM, l'interface centrale d'intégration PBX.
order: 4
---

Tous les endpoints CRM Lookup sont **scopés au workspace** et requièrent les scopes OAuth `client` et `crm`. Ces endpoints sont appelés par le Middleware CRM lors des événements PBX (appels entrants, appels sortants, sessions de chat).

**En-têtes :** `Authorization: Bearer {workspace-token}`

Le contexte client est résolu automatiquement depuis le token OAuth.

---

## GET /api/crm/lookup/contacts/search

Recherche des contacts dans le CRM connecté par numéro de téléphone ou adresse email. Généralement appelé lors d'un screen-pop quand un appel sonne sur le PBX.

**Paramètres de requête**

| Paramètre | Type | Requis | Description |
|---|---|---|---|
| `phone` | string | oui* | Numéro de téléphone à rechercher |
| `email` | string | oui* | Adresse email à rechercher |
| `display_name` | string | non | Nom affiché de l'appelant, utilisé par les intégrations URL-builder pour construire l'URL du contact |

*Au moins `phone` ou `email` est requis.

**Réponse `200`**

```json
{
  "contacts": [
    {
      "id": "crm-contact-uuid",
      "first_name": "Alice",
      "last_name": "Martin",
      "email": "alice.martin@acme.com",
      "phone_business_1": "+33142000000",
      "phone_mobile_1": "+33612345678",
      "company": "Acme Corp",
      "entity_url": "https://crm.example.com/contacts/123"
    }
  ]
}
```

> Si aucune correspondance n'est trouvée dans le CRM, un contact fictif est retourné afin que 3CX puisse tout de même déclencher l'étape de création d'appel.

---

## POST /api/crm/lookup/contacts

Crée un nouveau contact dans le CRM connecté.

**Corps de la requête**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `last_name` | string | oui | Nom de famille |
| `first_name` | string | non | Prénom |
| `civility` | string | non | Civilité |
| `email` | string | non | Adresse email |
| `phone` | string | non | Numéro de téléphone générique |
| `phone_business` | string | non | Numéro de téléphone professionnel |
| `phone_mobile` | string | non | Numéro de téléphone mobile |
| `custom_value` | string | non | Valeur de champ CRM personnalisé |
| `call_direction` | string | non | Direction de l'appel déclencheur (`inbound` ou `outbound`) |

**Réponse `201`**

```json
{
  "response": "ok",
  "contact": { ... }
}
```

**Réponse `400`** : le connecteur CRM n'a pas pu créer le contact.

---

## GET /api/crm/lookup/phone-calls

Retourne la liste des appels téléphoniques depuis le connecteur CRM connecté.

**Paramètres de requête**

| Paramètre | Description |
|---|---|
| `filter[direction]` | `inbound`, `outbound` ou `internal` |
| `filter[status]` | Statut de l'appel |
| `filter[answered]` | Booléen : si l'appel a été décroché |
| `filter[number_from]` | Numéro appelant |
| `filter[number_to]` | Numéro appelé |
| `filter[number_did]` | Numéro DID / groupe d'appel |
| `filter[start_time]` | Heure de début de l'appel |
| `filter[end_time]` | Heure de fin de l'appel |
| `filter[agent_email]` | Adresse email de l'agent |
| `filter[subject]` | Sujet de l'appel |
| `include` | Relations à inclure (séparées par virgule) : `segments`, `logs` |
| `sort` | Champ de tri : `start_time`, `end_time`, `created_at`, `updated_at`. Préfixez avec `-` pour décroissant |
| `per_page` | Résultats par page (défaut : 20) |

**Réponse `200`** : liste paginée d'objets appel.

---

## POST /api/crm/lookup/phone-calls

Enregistre un appel téléphonique terminé dans le CRM connecté. C'est l'endpoint principal appelé par le Middleware CRM lorsqu'un appel se termine sur le PBX.

**Corps de la requête**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `direction` | string | oui | `inbound`, `outbound` ou `internal` (insensible à la casse) |
| `status` | string | oui | `completed`, `failed`, `busy`, `no-answer`, `Missed` ou `Notanswered` |
| `number_from` | string | oui* | Numéro appelant |
| `number_to` | string | oui* | Numéro appelé |
| `number_external` | string | oui** | Numéro de la partie externe |
| `number_internal` | string | oui** | Extension interne |
| `source` | string | non | Identifiant de la source PBX (ex. `3cx`) |
| `answered` | boolean | non | Si l'appel a été décroché |
| `duration` | string/integer | non | Durée de l'appel |
| `start_time_utc` | string | non | Heure de début en UTC, format : `YYYY-MM-DDTHH:MM:SSZ` |
| `end_time_utc` | string | non | Heure de fin en UTC, format : `YYYY-MM-DDTHH:MM:SSZ` |
| `subject` | string | non | Sujet de l'appel |
| `body` | string | non | Notes ou extrait de transcription |
| `recording_url` | string | non | URL de l'enregistrement de l'appel |
| `agent_first_name` | string | non | Prénom de l'agent ayant pris l'appel |
| `agent_last_name` | string | non | Nom de l'agent ayant pris l'appel |
| `agent_email` | string | non | Email de l'agent ayant pris l'appel |
| `queue_extension` | string | non | Extension de la file d'attente ou du groupe d'appel |

*`number_from` et `number_to` sont mutuellement requis : fournissez les deux ou aucun.  
**`number_external` et `number_internal` sont mutuellement requis : fournissez les deux ou aucun.

**Réponse `201`**

```json
{
  "response": "success",
  "message": "Call saved successfully.",
  "call": { ... }
}
```

**Réponse `400`** : la journalisation des appels n'est pas activée pour ce compte.

---

## POST /api/crm/lookup/phone-calls/context

Crée ou met à jour un enregistrement de contexte d'appel pendant un appel en cours. Le contexte permet de pré-renseigner la fiche CRM afin qu'à la fin de l'appel, l'entrée complète puisse être enrichie sans dépendre uniquement du payload final.

**Corps de la requête**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `direction` | string | oui | `inbound` ou `outbound` |
| `number_from` | string | oui (si inbound) | Numéro appelant |
| `number_to` | string | oui (si outbound) | Numéro appelé |
| `source` | string | non | Identifiant de la source PBX (ex. `3cx`) |
| `start_time_utc` | string | non | Heure de début en UTC, format : `YYYY-MM-DDTHH:MM:SSZ` |
| `start_time_reference` | string | non | Référence temporelle du contexte : `call` (défaut) ou `segment` |
| `segment_dn_type` | string | non | Type de DN : `extension`, `trunk`, `call_queue`, `voicemail`, `ivr`, `external_number`, `call_flow` |
| `context_data` | array | non | Paires clé-valeur arbitraires à stocker avec le contexte |

**Réponse `201`**

```json
{
  "response": "success",
  "message": "Call context saved successfully.",
  "call_context_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

### Variante par token

Pour les cas où le Middleware CRM ne peut pas utiliser un token OAuth standard, un token de contexte pré-émis peut être utilisé à la place :

```
POST /api/crm/phone-calls-context/{token}/{tokenSecret}
```

Cet endpoint accepte le même corps de requête et ne nécessite pas d'en-tête `Authorization`. Le `token` (UUID) et le `tokenSecret` sont émis par CX-Engine et scopés à un client spécifique.

---

## POST /api/crm/lookup/chats

Enregistre une session de chat terminée dans le CRM connecté. Appelé par le Middleware CRM lorsqu'une session de chat se termine sur le PBX.

**Corps de la requête**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `email` | string | oui | Adresse email du client |
| `source` | string | non | Identifiant de la source PBX (ex. `3cx`) |
| `number_external` | string | non | Numéro externe ou identifiant du client |
| `name` | string | non | Nom affiché du client |
| `start_time_utc` | string | non | Heure de début en UTC, format : `YYYY-MM-DDTHH:MM:SSZ` |
| `end_time_utc` | string | non | Heure de fin en UTC, format : `YYYY-MM-DDTHH:MM:SSZ` |
| `duration` | string/integer | non | Durée du chat |
| `subject` | string | non | Sujet du chat |
| `chat_messages` | string | non | Transcription ou résumé du chat |
| `queue_extension` | string | non | Extension de la file d'attente ou du groupe d'appel |
| `entity_type` | string | non | Type d'entité CRM à lier au chat |
| `entity_id` | string | non | ID de l'entité CRM à lier au chat |
| `agent` | string | non | Identifiant de l'agent |
| `agent_first_name` | string | non | Prénom de l'agent ayant pris en charge le chat |
| `agent_last_name` | string | non | Nom de l'agent ayant pris en charge le chat |
| `agent_email` | string | non | Email de l'agent ayant pris en charge le chat |

**Réponse `201`**

```json
{
  "response": "success",
  "message": "Chat saved successfully.",
  "chat": { ... }
}
```

**Réponse `400`** : la journalisation des chats n'est pas activée pour ce compte.
