# Comment créer un signal Rodz et l'envoyer vers lemlist, entièrement par l'API ?

> Source: https://www.rodz.io/fr/guides/api/creer-et-router-un-signal-par-api/
> Mis à jour le 2026-10-12 · Peter Cools · Recette API · Changements de poste · API REST

## En bref

Créez le signal en brouillon avec POST /api/v1/signals/job-changes, lisez applied et warnings dans la réponse, connectez lemlist avec PUT /api/v1/integrations/lemlist, récupérez l'identifiant de campagne, puis routez le signal avec un PATCH sur destinations. Un dernier PATCH passe le statut à active : chaque lead coûte alors 2 crédits, plus 0,5 crédit par email trouvé.

## Chiffres clés

- Un signal créé sans `status` reste en **brouillon** (`draft`) : il ne produit rien et ne coûte rien tant qu'il n'est pas actif.
- Un changement de poste coûte **2 crédits** par lead, plus 0,5 crédit par email trouvé (`getEmails`), facturé uniquement en cas de succès.
- La limite quotidienne va de **1 à 999 999** leads (`dailyLeadLimit`, 100 par défaut) : c'est le plafond de dépense du signal.
- Un `PATCH` **fusionne** `config` avec la configuration enregistrée : envoyez seulement les champs à changer.

Coût: 2 crédits par lead (+0,5 crédit par email trouvé)

## Avant de commencer

- Une clé API Rodz (**Intégrations → API** dans le tableau de bord), exportée dans `RODZ_API_KEY`.
- Une clé API lemlist et une campagne lemlist avec au moins une étape.
- `curl` et, pour lire les réponses plus facilement, `jq`.

## Étapes

### 1. Choisissez le type de signal et ses valeurs autorisées

`GET /api/v1/signal-types` est le point d'entrée : chaque type y donne son `createEndpoint`, ses `configParameters`, son `pricingModel` et ses `outputFields`. Pour les changements de poste, les fonctions viennent de `GET /api/v1/personas` (le champ `name`) et les secteurs de `GET /api/v1/signals/industries` (à recopier tels quels : la correspondance est exacte).

`Catalogue, personas et secteurs`

```bash
curl -s "https://api.rodz.io/api/v1/signal-types" -H "Authorization: Bearer $RODZ_API_KEY" \
  | jq '.signalTypes[] | {signalTypeId, createEndpoint, creditsPerLead}'
curl -s "https://api.rodz.io/api/v1/personas" -H "Authorization: Bearer $RODZ_API_KEY"
curl -s -G "https://api.rodz.io/api/v1/signals/industries" -H "Authorization: Bearer $RODZ_API_KEY" \
  --data-urlencode "search=software"
```

### 2. Créez le signal en brouillon

Envoyez `name`, `config`, `dailyLeadLimit` et `duplicateHandling`. Sans `status`, le signal est créé en `draft`. Activez `getEmails` : une séquence email a besoin de l'adresse.

La réponse `201` renvoie le signal avec deux champs à lire : `applied` (les réglages réellement appliqués quand ils diffèrent de `config`) et `warnings` (les valeurs de filtre probablement erronées). Ce ne sont jamais des erreurs : le signal est créé quoi qu'il arrive.

`POST /api/v1/signals/job-changes`

```bash
curl -s -X POST "https://api.rodz.io/api/v1/signals/job-changes" \
  -H "Authorization: Bearer $RODZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nouveaux directeurs commerciaux SaaS France",
    "dailyLeadLimit": 30,
    "duplicateHandling": "refuse",
    "config": {
      "jobTitles": ["Sales Director"],
      "customTitles": ["Head of Revenue"],
      "companySizeFilters": ["51-200", "201-500"],
      "industryFilters": ["Software Development"],
      "locations": ["France"],
      "getEmails": true
    }
  }' | tee signal.json
export SIGNAL_ID=$(jq -r .id signal.json)
```

### 3. Connectez lemlist

`PUT /api/v1/integrations/lemlist` enregistre votre clé lemlist ; elle est vérifiée avant d'être stockée, puis chiffrée. `GET /api/v1/integrations` montre ensuite `connected: true`. HubSpot, Pipedrive et Google Sheets se connectent une fois par OAuth dans le tableau de bord (l'API répond `400 USE_DASHBOARD_OAUTH`).

`PUT /api/v1/integrations/lemlist`

```bash
curl -s -X PUT "https://api.rodz.io/api/v1/integrations/lemlist" \
  -H "Authorization: Bearer $RODZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"apiKey\": \"$LEMLIST_API_KEY\", \"label\": \"Équipe commerciale\"}"
```

### 4. Récupérez l'identifiant de la campagne

`GET /api/v1/integrations/lemlist/campaigns` renvoie `items[]` avec `id`, `name` et `status`. L'`id` est le `campaignId` de l'étape suivante. Un `409` signifie que lemlist n'est pas connecté.

`GET /api/v1/integrations/lemlist/campaigns`

```bash
curl -s "https://api.rodz.io/api/v1/integrations/lemlist/campaigns" \
  -H "Authorization: Bearer $RODZ_API_KEY" | jq '.items[] | {id, name, status}'
```

### 5. Routez le signal vers la campagne, puis activez-le

Un `PATCH` avec `destinations.lemlist.campaignId` branche le signal sur la campagne. Si plusieurs comptes lemlist sont connectés, ajoutez `integrationId`. Un second `PATCH` passe le signal en `active` : à partir de là, chaque lead livré est facturé et poussé dans la campagne.

`PATCH /api/v1/signals/{signal_id}`

```bash
curl -s -X PATCH "https://api.rodz.io/api/v1/signals/$SIGNAL_ID" \
  -H "Authorization: Bearer $RODZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"destinations": {"lemlist": {"campaignId": "cam_aBc123XyZ"}}}'

curl -s -X PATCH "https://api.rodz.io/api/v1/signals/$SIGNAL_ID" \
  -H "Authorization: Bearer $RODZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "active"}'
```

## Exemple de payload

Réponse `201 Created` de `POST /api/v1/signals/job-changes` (données fictives). `applied` vide = tout est appliqué tel qu'enregistré.

```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Nouveaux directeurs commerciaux SaaS France",
  "status": "draft",
  "signalTypeId": "job_changes",
  "webhookUrl": null,
  "config": {
    "jobTitles": ["Sales Director"],
    "customTitles": ["Head of Revenue"],
    "companySizeFilters": ["51-200", "201-500"],
    "industryFilters": ["Software Development"],
    "locations": ["France"],
    "getEmails": true
  },
  "dailyLeadLimit": 30,
  "leadsToday": 0,
  "leadsTotal": 0,
  "duplicateHandling": "refuse",
  "createdAt": "2026-10-12T08:00:00Z",
  "updatedAt": "2026-10-12T08:00:00Z",
  "lastLeadAt": null,
  "applied": {},
  "warnings": []
}
```

## Les appels, dans l'ordre

| #   | Appel                                                    | Rôle                                                       |
| --- | -------------------------------------------------------- | ---------------------------------------------------------- |
| 1   | `GET /api/v1/signal-types`                               | Choisir le type, lire `configParameters` et `pricingModel` |
| 2   | `GET /api/v1/personas`, `GET /api/v1/signals/industries` | Valeurs autorisées des filtres                             |
| 3   | `POST /api/v1/signals/job-changes`                       | Créer le signal en brouillon                               |
| 4   | `PUT /api/v1/integrations/lemlist`                       | Connecter lemlist (une fois par compte)                    |
| 5   | `GET /api/v1/integrations/lemlist/campaigns`             | Trouver le `campaignId`                                    |
| 6   | `PATCH /api/v1/signals/{signal_id}`                      | Router vers la campagne                                    |
| 7   | `PATCH /api/v1/signals/{signal_id}`                      | Passer en `active`                                         |

Les étapes 4 et 5 ne se refont pas pour chaque signal : une fois lemlist connecté, chaque nouveau signal n'a besoin que des étapes 3, 6 et 7.

## Les variables reçues par lemlist

Chaque lead arrive dans la campagne avec ses variables : `firstName`, `lastName`, `email`, `companyName`, `title`, `linkedinUrl`, `companyWebsite`, `signalName`, `matchedPersona`. Utilisez-les dans vos messages, par exemple « Félicitations pour votre arrivée chez {{companyName}} ».

## Dépannage

- **`422` à la création** : un champ de `config` n'existe pas pour ce type. Le message le nomme ; la liste exacte est dans `configParameters` de `GET /api/v1/signal-types`.
- **Aucun lead dans lemlist** : la campagne doit avoir au moins une étape, et un lead sans email ne peut pas entrer dans une séquence email.
- **Signal silencieux** : `GET /api/v1/signals/{signal_id}/funnel` montre combien de candidats chaque filtre a écartés.

## Questions fréquentes

### Pourquoi créer le signal en brouillon ?

Un brouillon ne produit aucun lead et ne coûte rien. Vous pouvez relire `applied` et `warnings`, brancher la destination, puis activer. Activer un signal sans destination ni webhook fonctionne aussi : les leads se lisent alors avec `GET /api/v1/signals/{signal_id}/leads`.

### Que signifient `applied` et `warnings` ?

`applied` liste les réglages appliqués autrement que stockés (par exemple `maxJobAgeDays` ramené à son minimum de 180). `warnings` signale les valeurs de filtre probablement erronées, comme un secteur inconnu ou une catégorie envoyée avec ses propres secteurs. Le signal est créé dans tous les cas.

### Comment modifier un filtre sans tout renvoyer ?

`PATCH /api/v1/signals/{signal_id}` fusionne `config` avec la configuration enregistrée : envoyez seulement les champs à changer. Pour vider une liste, envoyez-la vide, par exemple `"customTitles": []`.

### Puis-je envoyer le même signal dans un CRM et dans lemlist ?

Oui. `destinations` accepte plusieurs destinations à la fois, par exemple `hubspot` (`enabled: true`) et `lemlist` (`campaignId`). HubSpot et Pipedrive doivent d'abord être connectés par OAuth dans le tableau de bord.

### Comment tester sans attendre un vrai lead ?

Si le signal a un `webhookUrl`, `POST /api/v1/signals/{signal_id}/test-webhook` envoie un lead d'exemple marqué `signal.is_test: true`. Pour lemlist, vérifiez le premier lead réel dans la campagne après activation.

## Sources

- [Référence de l’API Rodz : Create Job Changes signal, Update signal, Integrations](https://api.rodz.io/docs)
- [Spécification OpenAPI de l’API Rodz](https://api.rodz.io/openapi.json)

## Guides associés

- https://www.rodz.io/fr/guides/api/recuperer-les-leads-d-un-signal/
- https://www.rodz.io/fr/guides/api/recepteur-webhook-hmac/
- https://www.rodz.io/fr/guides/cas-usage/changements-de-poste-vers-lemlist/
