{"openapi":"3.1.0","info":{"title":"API Replexa","version":"2.0.0","description":"API REST de Replexa : campagnes, leads, boîtes d'envoi, inbox, agents IA et webhooks.\n\n[Authentification](https://docs.replexa.eu/authentification) · [Pagination](https://docs.replexa.eu/pagination) · [Limites de débit](https://docs.replexa.eu/limites) · [Erreurs](https://docs.replexa.eu/erreurs) · [Webhooks](https://docs.replexa.eu/webhooks)"},"servers":[{"url":"https://app.replexa.eu/api/v2","description":"Production"}],"security":[{"apiKey":[]},{"oauth2":["replexa:read"]}],"tags":[{"name":"Campagnes","description":"Création, réglages, lancement et pause des campagnes d'emails."},{"name":"Analytics","description":"Statistiques d'envoi, d'ouverture, de réponse et d'opportunités."},{"name":"Sous-séquences","description":"Séquences secondaires déclenchées par une réponse ou un statut d'intérêt."},{"name":"Leads","description":"Contacts prospectés : création, import, recherche, déplacement et statut d'intérêt."},{"name":"Listes de leads","description":"Listes qui stockent des leads hors campagne."},{"name":"Enrichissement IA","description":"Variables générées par l'IA pour chaque lead d'une campagne (recherche web, personnalisation)."},{"name":"Labels et tags","description":"Statuts d'intérêt personnalisés des leads et tags des boîtes d'envoi."},{"name":"Blocklist","description":"Emails et domaines qui ne recevront jamais de message."},{"name":"Boîtes d'envoi","description":"Boîtes SMTP/IMAP ou OAuth (Google, Microsoft) qui envoient les campagnes."},{"name":"Emails / Inbox","description":"Inbox unifiée : emails envoyés et reçus, réponses, transferts."},{"name":"Agents IA","description":"Agents qui lisent les réponses, rédigent et envoient (ou proposent) la suite."},{"name":"Outils et skills","description":"Outils HTTP ou MCP et instructions réutilisables mis à disposition des agents."},{"name":"Rédaction IA","description":"Variantes de texte et contrôle du spintax."},{"name":"Intégrations","description":"Google Agenda, Airtable et CRM (HubSpot, Pipedrive, Salesforce) connectés au workspace."},{"name":"Webhooks","description":"Évènements signés envoyés en POST vers vos URLs."},{"name":"REST Hooks","description":"Abonnements utilisés par Zapier et Make (subscribe / unsubscribe)."},{"name":"Workspace","description":"Réglages du workspace, membres, invitations et tableau de bord."},{"name":"Clés API","description":"Clés d'accès à l'API, avec scopes et rôle."},{"name":"Facturation","description":"Abonnement et consommation du workspace."}],"x-tagGroups":[{"name":"Prospection","tags":["Campagnes","Analytics","Sous-séquences","Leads","Listes de leads","Enrichissement IA","Labels et tags","Blocklist"]},{"name":"Envoi et réception","tags":["Boîtes d'envoi","Emails / Inbox"]},{"name":"Intelligence artificielle","tags":["Agents IA","Outils et skills","Rédaction IA"]},{"name":"Automatisation","tags":["Webhooks","REST Hooks","Intégrations"]},{"name":"Administration","tags":["Workspace","Clés API","Facturation"]}],"paths":{"/campaigns":{"get":{"operationId":"getCampaigns","tags":["Campagnes"],"summary":"Lister les campagnes","description":"Campagnes du workspace, des plus récentes aux plus anciennes.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Filtre sur le nom (contient, sans tenir compte de la casse).","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Statut exact : 0 brouillon, 1 active, 2 en pause, 3 terminée.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Campaign"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postCampaigns","tags":["Campagnes"],"summary":"Créer une campagne","description":"Crée une campagne en brouillon (statut 0), rattachée à l'utilisateur de la clé (`owned_by`). Sans `campaign_schedule`, le planning par défaut s'applique (lundi au vendredi, 9 h à 17 h, Europe/Paris) ; sans `sequences`, la campagne n'a aucune étape.\n\nDans une étape, `delay` (unité `delay_unit`, jours par défaut) est l'attente **après** cette étape avant la suivante. Les boîtes de `email_list` et les tags de `email_tag_list` doivent appartenir au workspace (sinon 400). Lancez ensuite la campagne avec `POST /campaigns/{id}/activate`.\n\n**Scope** : `campaigns:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignCreate"},"example":{"name":"Relance salons octobre","email_list":["jeanne@exemple.fr"],"sequences":[{"steps":[{"type":"email","delay":3,"delay_unit":"days","variants":[{"subject":"Votre stand au salon","body":"Bonjour {{first_name}},\n\nJ'ai vu que {{company_name}} exposait au salon de Lyon…"}]},{"type":"email","delay":0,"variants":[{"subject":"","body":"Bonjour {{first_name}}, je me permets de vous relancer…"}]}]}],"daily_limit":50,"stop_on_reply":true}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Relance salons octobre\",\n  \"email_list\": [\n    \"jeanne@exemple.fr\"\n  ],\n  \"sequences\": [\n    {\n      \"steps\": [\n        {\n          \"type\": \"email\",\n          \"delay\": 3,\n          \"delay_unit\": \"days\",\n          \"variants\": [\n            {\n              \"subject\": \"Votre stand au salon\",\n              \"body\": \"Bonjour {{first_name}},\\n\\nJ'\\''ai vu que {{company_name}} exposait au salon de Lyon…\"\n            }\n          ]\n        },\n        {\n          \"type\": \"email\",\n          \"delay\": 0,\n          \"variants\": [\n            {\n              \"subject\": \"\",\n              \"body\": \"Bonjour {{first_name}}, je me permets de vous relancer…\"\n            }\n          ]\n        }\n      ]\n    }\n  ],\n  \"daily_limit\": 50,\n  \"stop_on_reply\": true\n}'"}]}},"/campaigns/{id}":{"get":{"operationId":"getCampaignsById","tags":["Campagnes"],"summary":"Lire une campagne","description":"Tous les réglages de la campagne : séquences, planning, boîtes d'envoi et options.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchCampaignsById","tags":["Campagnes"],"summary":"Modifier une campagne","description":"Met à jour les seuls champs envoyés ; un tableau (`sequences`, `email_list`…) remplace entièrement l'ancien. Le statut ne se modifie pas ici : utilisez `activate` et `pause`. Les champs inconnus sont ignorés. Une boîte ou un tag absent du workspace renvoie 400.\n\n**Scope** : `campaigns:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPatch"},"example":{"daily_limit":80,"email_gap":15,"open_tracking":false}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"daily_limit\": 80,\n  \"email_gap\": 15,\n  \"open_tracking\": false\n}'"}]},"delete":{"operationId":"deleteCampaignsById","tags":["Campagnes"],"summary":"Supprimer une campagne","description":"Suppression définitive. Sont supprimés avec elle : ses leads, ses sous-séquences, ses évènements (statistiques), les webhooks limités à cette campagne et ses traitements IA. Les emails de l'inbox sont conservés, sans lien vers la campagne. Renvoie la campagne telle qu'elle était avant suppression.\n\n**Scope** : `campaigns:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/{id}/activate":{"post":{"operationId":"postCampaignsByIdActivate","tags":["Campagnes"],"summary":"Lancer une campagne","description":"Passe la campagne au statut 1 (active) et efface `not_sending_status` ; le worker commence l'envoi au prochain créneau du planning. Sert aussi à reprendre une campagne en pause.\n\nRefus (400) si la séquence n'a aucune étape, si une étape n'a que des variantes désactivées (`v_disabled`) ou si ni `email_list` ni `email_tag_list` ne sont renseignés. Refus (402) si l'abonnement ne permet plus l'envoi (impayé, résilié, essai expiré). La présence de leads n'est pas vérifiée : voir `GET /campaigns/{id}/sending-status`.\n\n**Scope** : `campaigns:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/activate\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/{id}/pause":{"post":{"operationId":"postCampaignsByIdPause","tags":["Campagnes"],"summary":"Mettre une campagne en pause","description":"Passe une campagne qui envoie (statut 1 active, ou 4 sous-séquences en cours) au statut 2 (en pause) ; ses sous-séquences s'arrêtent aussi. Les leads gardent leur position dans la séquence ; l'envoi reprend avec `POST /campaigns/{id}/activate`.\n\nRefus (400) pour une campagne en brouillon, terminée, déjà en pause ou suspendue (statuts 0, 2, 3, -1, -2, -99).\n\n**Scope** : `campaigns:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/pause\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/{id}/duplicate":{"post":{"operationId":"postCampaignsByIdDuplicate","tags":["Campagnes"],"summary":"Dupliquer une campagne","description":"Crée une copie en brouillon avec les mêmes séquences, planning, boîtes d'envoi, options et variables. Les leads, les sous-séquences et les statistiques ne sont pas copiés. Sans `name`, la copie s'appelle « nom d'origine (copie) ». La copie appartient à l'appelant (`owned_by` = utilisateur de la session ou créateur de la clé API), pas au propriétaire de l'original. Le corps peut être vide.\n\n**Scope** : `campaigns:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:create","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Nom de la copie. Par défaut, le nom d'origine suivi de « (copie) ».","type":"string"}}},"example":{"name":"Relance salons novembre"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/duplicate\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Relance salons novembre\"\n}'"}]}},"/campaigns/{id}/sending-status":{"get":{"operationId":"getCampaignsByIdSendingStatus","tags":["Campagnes"],"summary":"Diagnostiquer l'envoi d'une campagne","description":"Répond à « pourquoi la campagne n'envoie pas ? ». `diagnostics.status` vaut `healthy` quand tout va bien ; sinon, la première cause trouvée dans cet ordre : statut de la campagne (brouillon, pause, terminée…), abonnement bloqué (`plan_sending_blocked`), quota mensuel d'emails atteint (`plan_email_limit_met`), aucune boîte active, hors planning, limite quotidienne de la campagne, limite quotidienne de toutes les boîtes, relances en attente de leur délai, aucun lead à contacter, limite de nouveaux leads.\n\nLes boîtes examinées sont celles de `email_list` et celles qui portent un tag de `email_tag_list`, comme pour l'envoi. Les compteurs « quotidiens » portent sur les 24 dernières heures glissantes et ne comptent que la séquence principale (pas les envois des sous-séquences).\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"campaign_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Campagne diagnostiquée."},"diagnostics":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","campaign_draft","campaign_paused","campaign_completed","campaign_running_subsequences","campaign_bounce_protect","campaign_accounts_unhealthy","campaign_account_suspended","plan_sending_blocked","plan_email_limit_met","no_accounts_available","out_of_schedule","daily_limit_met","account_daily_limit_met","follow_up_delay_not_met","waiting_for_leads","new_lead_limit_met"]},"accounts_summary":{"type":"object","properties":{"total_connected":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Boîtes de `email_list` qui ne sont pas en erreur."},"available":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Boîtes actives qui n'ont pas atteint leur limite quotidienne."},"unavailable":{"type":"object","properties":{"daily_limit_hit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"disconnected":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"paused":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["daily_limit_hit","disconnected","paused"],"additionalProperties":false}},"required":["total_connected","available","unavailable"],"additionalProperties":false},"campaign_daily_limit":{"type":"object","properties":{"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Emails envoyés par la campagne sur les dernières 24 h."},"limit_hit":{"type":"boolean"}},"required":["limit","sent","limit_hit"],"additionalProperties":false},"plan_monthly_emails":{"type":"object","properties":{"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Quota mensuel d'emails du plan (`null` = illimité)."},"remaining":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"limit_hit":{"type":"boolean"}},"required":["limit","remaining","limit_hit"],"additionalProperties":false},"new_lead_limit":{"type":"object","properties":{"enabled":{"type":"boolean"},"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"contacted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nouveaux leads contactés sur les dernières 24 h."},"limit_hit":{"type":"boolean"}},"required":["enabled","limit","contacted","limit_hit"],"additionalProperties":false},"schedule_status":{"type":"object","properties":{"in_schedule":{"type":"boolean"}},"required":["in_schedule"],"additionalProperties":false},"follow_ups_waiting":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"earliest_wait_time_seconds":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Secondes avant la prochaine relance due."}},"required":["count","earliest_wait_time_seconds"],"additionalProperties":false},"leads_status":{"type":"object","properties":{"ready_now":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads actifs dont l'envoi est dû maintenant."}},"required":["ready_now"],"additionalProperties":false}},"required":["status","accounts_summary","campaign_daily_limit","plan_monthly_emails","new_lead_limit","schedule_status","follow_ups_waiting","leads_status"],"additionalProperties":false},"summary":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","campaign_draft","campaign_paused","campaign_completed","campaign_running_subsequences","campaign_bounce_protect","campaign_accounts_unhealthy","campaign_account_suspended","plan_sending_blocked","plan_email_limit_met","no_accounts_available","out_of_schedule","daily_limit_met","account_daily_limit_met","follow_up_delay_not_met","waiting_for_leads","new_lead_limit_met"]},"status_message":{"type":"string","description":"Explication en français."},"last_healthy_send_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier envoi de la campagne."}},"required":["status","status_message","last_healthy_send_at"],"additionalProperties":false}},"required":["campaign_id","diagnostics","summary"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/sending-status\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/{id}/variables":{"post":{"operationId":"postCampaignsByIdVariables","tags":["Campagnes"],"summary":"Déclarer des variables de campagne","description":"Ajoute des noms de variables à `custom_variables` (proposées par l'autocomplétion de l'éditeur et reprises à l'export). Les variables déjà déclarées sont conservées : l'appel est idempotent. Les valeurs propres à chaque lead se renseignent sur les leads, dans `custom_variables`.\n\n**Scope** : `campaigns:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"variables":{"type":"array","items":{"type":"string","minLength":1},"description":"Noms des variables à ajouter, sans accolades (ex. `civilite`)."}},"required":["variables"]},"example":{"variables":["civilite","accroche"]}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/variables\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"variables\": [\n    \"civilite\",\n    \"accroche\"\n  ]\n}'"}]}},"/campaigns/{id}/leads/clean":{"post":{"operationId":"postCampaignsByIdLeadsClean","tags":["Campagnes"],"summary":"Nettoyer les leads d'une campagne","description":"Nettoyages gratuits, sans IA, sur tous les leads de la campagne (50 000 au plus) :\n\n- `trim` : espaces en trop, caractères invisibles, encodage cassé ;\n- `names` : majuscules et accents des prénoms et noms ;\n- `company` : formes juridiques retirées des noms d'entreprise.\n\n`dedupe` supprime les doublons d'email jamais contactés : `campaign` dans la campagne (le lead déjà contacté, sinon le plus ancien, est gardé), `workspace` en plus ceux déjà présents dans une autre campagne. Avec `dry_run: true` (défaut), rien n'est écrit : la réponse donne le nombre de changements et des exemples. Avec `dry_run: false`, les modifications et suppressions sont appliquées.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ops":{"default":[],"type":"array","items":{"type":"string","enum":["trim","names","company"]}},"dedupe":{"default":"none","type":"string","enum":["none","campaign","workspace"]},"dry_run":{"default":true,"type":"boolean"}}},"example":{"ops":["trim","names","company"],"dedupe":"campaign","dry_run":true}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"scanned":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads examinés."},"changed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads modifiés (ou qui le seraient)."},"examples":{"type":"array","items":{"type":"object","properties":{"lead_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":["string","null"]},"changes":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"before":{},"after":{}},"required":["before","after"],"additionalProperties":false}}},"required":["lead_id","email","changes"],"additionalProperties":false},"description":"Jusqu'à 20 exemples de changements, champ par champ."},"duplicates":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Doublons supprimés (ou qui le seraient)."},"duplicate_examples":{"type":"array","items":{"type":"object","properties":{"lead_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":["string","null"]},"reason":{"type":"string"}},"required":["lead_id","email","reason"],"additionalProperties":false},"description":"Jusqu'à 10 exemples de doublons."}},"required":["scanned","changed","examples","duplicates","duplicate_examples"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/leads/clean\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"ops\": [\n    \"trim\",\n    \"names\",\n    \"company\"\n  ],\n  \"dedupe\": \"campaign\",\n  \"dry_run\": true\n}'"}]}},"/campaigns/{id}/leads/ai-preview":{"post":{"operationId":"postCampaignsByIdLeadsAiPreview","tags":["Enrichissement IA"],"summary":"Tester une colonne IA","description":"Applique une colonne IA à 5 leads au plus de la campagne (les premiers par identifiant, ou ceux de `lead_ids`) et renvoie les valeurs proposées, sans rien enregistrer. La consommation IA est décomptée du workspace.\n\n`template` choisit une consigne prête à l'emploi (voir `GET /lead-ai-runs/templates`) ; avec `custom`, `prompt` est obligatoire (400 sinon). `target` désigne le champ standard ou la variable de lead à remplir ; une variable commence par une lettre (lettres, chiffres et `_`, 40 caractères au plus) et ne reprend pas un nom standard. `read_website` fait lire la page d'accueil du lead (site, ou domaine de l'email). Renvoie 402 si les crédits IA du mois sont épuisés (ou l'abonnement suspendu), 503 si l'IA n'est pas configurée sur l'instance (`ANTHROPIC_API_KEY` absente).\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"leads:update","x-min-role":"member","x-rate-limit":"20/min","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"config":{"type":"object","properties":{"template":{"type":"string","enum":["company_name","first_name","salutation","icebreaker","custom"]},"prompt":{"type":"string","maxLength":2000},"target":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"field"},"name":{"type":"string","enum":["first_name","last_name","company_name","job_title","website","personalization"]}},"required":["kind","name"]},{"type":"object","properties":{"kind":{"type":"string","const":"variable"},"name":{"type":"string","minLength":1,"maxLength":40}},"required":["kind","name"]}]},"read_website":{"type":"boolean"}},"required":["template","target"]},"limit":{"default":5,"type":"integer","minimum":1,"maximum":5},"lead_ids":{"maxItems":5,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["config"]},"example":{"config":{"template":"icebreaker","target":{"kind":"variable","name":"accroche"},"read_website":true},"limit":3}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LeadAiPreview"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"503":{"$ref":"#/components/responses/E503"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/leads/ai-preview\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"config\": {\n    \"template\": \"icebreaker\",\n    \"target\": {\n      \"kind\": \"variable\",\n      \"name\": \"accroche\"\n    },\n    \"read_website\": true\n  },\n  \"limit\": 3\n}'"}]}},"/campaigns/{id}/leads/ai-runs":{"get":{"operationId":"getCampaignsByIdLeadsAiRuns","tags":["Enrichissement IA"],"summary":"Lister les traitements IA d'une campagne","description":"Les 10 derniers traitements IA de la campagne, du plus récent au plus ancien, avec leur progression. Pas de pagination.\n\n**Scope** : `leads:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"leads:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LeadAiRun"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/leads/ai-runs\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postCampaignsByIdLeadsAiRuns","tags":["Enrichissement IA"],"summary":"Lancer une colonne IA sur les leads","description":"Lance le traitement de tous les leads de la campagne en tâche de fond (file de jobs du worker) et renvoie le traitement au statut `pending`. Suivez-le avec `GET /lead-ai-runs/{id}`. Jusqu'à 200 leads, ou quand `read_website` est actif, les leads sont traités par paquets de 20 ; au-delà, via la Message Batches API (résultat en quelques minutes à quelques heures).\n\nChaque lead dont la valeur change est mis à jour ; une valeur vide ne remplace rien. Une variable de destination est aussi déclarée sur la campagne. Mêmes règles de configuration que `POST /campaigns/{id}/leads/ai-preview`. Refus (409) si un traitement est déjà en cours sur la campagne, (400) si la campagne n'a aucun lead. Les crédits IA sont vérifiés au lancement seulement. Renvoie 402 si les crédits IA du mois sont épuisés (ou l'abonnement suspendu), 503 si l'IA n'est pas configurée sur l'instance (`ANTHROPIC_API_KEY` absente).\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"leads:update","x-min-role":"member","x-rate-limit":"20/min","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la campagne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadAiConfig"},"example":{"template":"custom","prompt":"Écris le secteur d'activité de l'entreprise en deux ou trois mots.","target":{"kind":"variable","name":"secteur"},"read_website":false}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadAiRun"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"503":{"$ref":"#/components/responses/E503"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/campaigns/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/leads/ai-runs\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"template\": \"custom\",\n  \"prompt\": \"Écris le secteur d'\\''activité de l'\\''entreprise en deux ou trois mots.\",\n  \"target\": {\n    \"kind\": \"variable\",\n    \"name\": \"secteur\"\n  },\n  \"read_website\": false\n}'"}]}},"/lead-ai-runs/templates":{"get":{"operationId":"getLeadAiRunsTemplates","tags":["Enrichissement IA"],"summary":"Lister les modèles de colonnes IA","description":"Consignes prêtes à l'emploi utilisables dans `template`, avec leur destination et leur réglage `read_website` par défaut. `batch_threshold` : nombre de leads au-delà duquel un traitement passe par la Message Batches API.\n\n**Scope** : `leads:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"leads:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"batch_threshold":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["company_name","first_name","salutation","icebreaker"]},"label":{"type":"string"},"prompt":{"type":"string"},"target":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"field"},"name":{"type":"string","enum":["first_name","last_name","company_name","job_title","website","personalization"]}},"required":["kind","name"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"variable"},"name":{"type":"string","minLength":1,"maxLength":40}},"required":["kind","name"],"additionalProperties":false}]},"read_website":{"type":"boolean"}},"required":["id","label","prompt","target","read_website"],"additionalProperties":false}}},"required":["batch_threshold","items"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/lead-ai-runs/templates\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/lead-ai-runs/{id}":{"get":{"operationId":"getLeadAiRunsById","tags":["Enrichissement IA"],"summary":"Lire un traitement IA","description":"État et progression d'un traitement : `processed` sur `total`, leads modifiés (`updated`) et en erreur (`failed`), tokens consommés.\n\n**Scope** : `leads:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"leads:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du traitement IA (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadAiRun"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/lead-ai-runs/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/lead-ai-runs/{id}/cancel":{"post":{"operationId":"postLeadAiRunsByIdCancel","tags":["Enrichissement IA"],"summary":"Annuler un traitement IA","description":"Arrête un traitement `pending` ou `running` (et annule le lot côté Anthropic s'il y en a un), puis le renvoie au statut `cancelled`. Les leads déjà traités gardent leur nouvelle valeur. Sur un traitement déjà terminé, rien ne change et il est renvoyé tel quel.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du traitement IA (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadAiRun"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/lead-ai-runs/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/cancel\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/analytics":{"get":{"operationId":"getCampaignsAnalytics","tags":["Analytics"],"summary":"Lire les statistiques par campagne","description":"Une ligne par campagne du workspace (ou des campagnes demandées), en tableau JSON. Les compteurs d'évènements (envois, ouvertures, réponses, clics, bounces, désinscriptions) portent sur la période ; les états des leads (`leads_count`, `completed_count`, `remaining_count`, `positive_count`…) sont toujours l'état actuel. Sans période, tout l'historique est compté. Refus (400) si `id` / `ids` n'est pas un UUID ou si une date est illisible.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"id","in":"query","required":false,"description":"Limite à une campagne.","schema":{"type":"string","format":"uuid"}},{"name":"ids","in":"query","required":false,"description":"Limite à plusieurs campagnes : répétez le paramètre (`ids=…&ids=…`). Cumulable avec `id`.","schema":{"type":"string","format":"uuid"}},{"name":"start_date","in":"query","required":false,"description":"Début de période inclus (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-01"},{"name":"end_date","in":"query","required":false,"description":"Fin de période incluse (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-31"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"campaign_name":{"type":"string"},"campaign_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"campaign_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"leads_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads de la campagne (état actuel)."},"contacted_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant reçu au moins un email sur la période."},"emails_sent_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Emails envoyés sur la période."},"new_leads_contacted_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant reçu la première étape sur la période."},"open_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Ouvertures (toutes)."},"open_count_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant ouvert."},"reply_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Réponses (toutes)."},"reply_count_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant répondu."},"reply_count_automatic":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Réponses automatiques (absences, accusés)."},"link_click_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Clics (tous)."},"link_click_count_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant cliqué."},"bounced_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads en bounce."},"unsubscribed_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads désinscrits."},"completed_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant terminé la séquence (état actuel)."},"remaining_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads encore dans la séquence, actifs ou en pause (état actuel)."},"positive_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads au statut d'intérêt positif (état actuel)."},"negative_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads au statut d'intérêt négatif (état actuel)."},"neutral_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads au statut d'intérêt neutre (état actuel)."},"completion_pct":{"type":"number","description":"Part des leads sortis de la séquence, en % (une décimale)."},"total_opportunities":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Égal à `positive_count`."},"total_opportunity_value":{"type":"number","description":"`total_opportunities` × `pl_value` de la campagne."}},"required":["campaign_name","campaign_id","campaign_status","leads_count","contacted_count","emails_sent_count","new_leads_contacted_count","open_count","open_count_unique","reply_count","reply_count_unique","reply_count_automatic","link_click_count","link_click_count_unique","bounced_count","unsubscribed_count","completed_count","remaining_count","positive_count","negative_count","neutral_count","completion_pct","total_opportunities","total_opportunity_value"],"additionalProperties":false}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/analytics?start_date=2026-10-01&end_date=2026-10-31\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/analytics/overview":{"get":{"operationId":"getCampaignsAnalyticsOverview","tags":["Analytics"],"summary":"Lire la vue d'ensemble des statistiques","description":"Totaux agrégés sur les campagnes demandées, ou sur tout le workspace sans `id` ni `ids`. Les compteurs `_unique` comptent des leads distincts ; les objets `_by_step` les répartissent par index d'étape. Les opportunités comptent les leads passés à un statut d'intérêt positif pendant la période. Les évènements des sous-séquences (envois, ouvertures, clics, réponses de leurs emails) ne sont pas comptés. Refus (400) si `id` / `ids` n'est pas un UUID ou si une date est illisible.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"id","in":"query","required":false,"description":"Limite à une campagne.","schema":{"type":"string","format":"uuid"}},{"name":"ids","in":"query","required":false,"description":"Limite à plusieurs campagnes : répétez le paramètre (`ids=…&ids=…`). Cumulable avec `id`.","schema":{"type":"string","format":"uuid"}},{"name":"start_date","in":"query","required":false,"description":"Début de période inclus (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-01"},{"name":"end_date","in":"query","required":false,"description":"Fin de période incluse (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-31"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignAnalyticsOverview"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/analytics/overview?start_date=2026-10-01&end_date=2026-10-31\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/analytics/daily":{"get":{"operationId":"getCampaignsAnalyticsDaily","tags":["Analytics"],"summary":"Lire les statistiques par jour","description":"Une ligne par jour (UTC) ayant eu au moins un évènement, du plus ancien au plus récent ; les jours sans activité sont absents. Tableau JSON, sans pagination. Les évènements des sous-séquences ne sont pas comptés. Refus (400) si `campaign_id` n'est pas un UUID ou si une date est illisible.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"campaign_id","in":"query","required":false,"description":"Limite à une campagne (sinon tout le workspace).","schema":{"type":"string","format":"uuid"}},{"name":"start_date","in":"query","required":false,"description":"Début de période inclus (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-01"},{"name":"end_date","in":"query","required":false,"description":"Fin de période incluse (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-31"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"Jour (UTC)."},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"contacted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"new_leads_contacted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"opened":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_opened":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies_automatic":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_replies_automatic":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"clicks":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_clicks":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"opportunities":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_opportunities":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["date","sent","contacted","new_leads_contacted","opened","unique_opened","replies","unique_replies","replies_automatic","unique_replies_automatic","clicks","unique_clicks","opportunities","unique_opportunities"],"additionalProperties":false}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/analytics/daily?start_date=2026-10-01&end_date=2026-10-31\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/campaigns/analytics/steps":{"get":{"operationId":"getCampaignsAnalyticsSteps","tags":["Analytics"],"summary":"Lire les statistiques par étape et variante","description":"Une ligne par couple (étape, variante) ayant eu des évènements, triées par étape puis variante. Les statuts d'intérêt (opportunités, RDV, gagnés) sont attribués à l'étape et à la variante de la dernière réponse du lead. Les étapes des sous-séquences ne sont pas comptées.\n\nRefus (400) sans `campaign_id` (les index d'étape de campagnes différentes ne s'additionnent pas), si ce n'est pas un UUID ou si une date est illisible.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"campaign_id","in":"query","required":true,"description":"Campagne analysée.","schema":{"type":"string","format":"uuid"}},{"name":"start_date","in":"query","required":false,"description":"Début de période inclus (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-01"},{"name":"end_date","in":"query","required":false,"description":"Fin de période incluse (AAAA-MM-JJ).","schema":{"type":"string","format":"date"},"example":"2026-10-31"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","description":"Index de l'étape, à partir de `\"0\"`."},"variant":{"type":"string","description":"Index de la variante : `\"0\"` = A, `\"1\"` = B…"},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"opened":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_opened":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies_automatic":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_replies_automatic":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"clicks":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_clicks":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"opportunities":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads positifs dont la dernière réponse portait sur cette étape et variante."},"unique_opportunities":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"meetings_booked":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"won":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["step","variant","sent","opened","unique_opened","replies","unique_replies","replies_automatic","unique_replies_automatic","clicks","unique_clicks","opportunities","unique_opportunities","meetings_booked","won"],"additionalProperties":false}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/campaigns/analytics/steps?campaign_id=0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90&start_date=2026-10-01&end_date=2026-10-31\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/dashboard":{"get":{"operationId":"getDashboard","tags":["Analytics"],"summary":"Lire le tableau de bord","description":"Données de la page d'accueil en un appel : totaux de la période et de la période précédente de même durée, série quotidienne (jours calculés dans le fuseau `tz`), jusqu'à 6 campagnes actives avec leur avancement, les 6 dernières réponses positives et les 5 derniers brouillons d'agent IA en attente de validation. Une valeur de `days` autre que 7, 30 ou 90 donne 30.\n\nLes aperçus exigent des scopes supplémentaires : sans `emails:read`, `positives` est une liste vide ; sans `ai_agents:read`, `drafts` est une liste vide (`drafts_total` reste renseigné). Une session de l'interface n'est limitée que par son rôle.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","parameters":[{"name":"days","in":"query","required":false,"description":"Durée de la période en jours (défaut 30).","schema":{"type":"integer","enum":[7,30,90]},"example":30},{"name":"tz","in":"query","required":false,"description":"Fuseau IANA des jours de la série (défaut `UTC`, ignoré s'il est inconnu).","schema":{"type":"string"},"example":"Europe/Paris"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"days":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Durée de la période retenue (7, 30 ou 90)."},"tz":{"type":"string","description":"Fuseau retenu (`UTC` si `tz` est absent ou invalide)."},"totals":{"type":"object","properties":{"current":{"type":"object","properties":{"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Emails envoyés."},"opened":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant ouvert."},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant répondu."},"bounces":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads en bounce."},"positive":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à un statut positif."},"negative":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à un statut négatif."},"meetings":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à « RDV pris »."}},"required":["sent","opened","replies","bounces","positive","negative","meetings"],"additionalProperties":false},"previous":{"type":"object","properties":{"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Emails envoyés."},"opened":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant ouvert."},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ayant répondu."},"bounces":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads en bounce."},"positive":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à un statut positif."},"negative":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à un statut négatif."},"meetings":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à « RDV pris »."}},"required":["sent","opened","replies","bounces","positive","negative","meetings"],"additionalProperties":false,"description":"Mêmes totaux sur la période précédente de même durée."}},"required":["current","previous"],"additionalProperties":false},"series":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"positive":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["date","sent","replies","positive"],"additionalProperties":false},"description":"Un point par jour de la période, jours sans activité compris."},"campaigns":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"leads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"contacted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remaining":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"positive":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"negative":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"bounces":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"completion_pct":{"type":"number"},"timestamp_last_sent":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier envoi."}},"required":["id","name","status","leads","contacted","completed","remaining","sent","replies","positive","negative","bounces","completion_pct","timestamp_last_sent"],"additionalProperties":false},"description":"Jusqu'à 6 campagnes actives (statut 1 ou 4), les plus récemment envoyées d'abord. Compteurs sur toute la vie de la campagne."},"positives":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'email reçu."},"thread_id":{"type":"string"},"subject":{"type":"string"},"preview":{"type":["string","null"]},"from_email":{"type":["string","null"]},"from_name":{"type":["string","null"]},"company":{"type":["string","null"]},"interest_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"campaign_name":{"type":["string","null"]},"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de l'email."}},"required":["id","thread_id","subject","preview","from_email","from_name","company","interest_status","campaign_name","timestamp"],"additionalProperties":false},"description":"Les 6 dernières réponses reçues classées positives (statuts intégrés et labels personnalisés positifs)."},"drafts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'activité de l'agent."},"thread_id":{"type":["string","null"]},"to":{"type":["string","null"]},"company":{"type":["string","null"]},"subject":{"type":"string"},"preview":{"type":["string","null"]},"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date du brouillon."}},"required":["id","thread_id","to","company","subject","preview","timestamp"],"additionalProperties":false},"description":"Les 5 derniers brouillons d'agent IA en attente de validation."},"drafts_total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre total de brouillons en attente."}},"required":["days","tz","totals","series","campaigns","positives","drafts","drafts_total"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/dashboard?days=30&tz=Europe%2FParis\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/subsequences":{"get":{"operationId":"getSubsequences","tags":["Sous-séquences"],"summary":"Lister les sous-séquences","description":"Sous-séquences du workspace, des plus récentes aux plus anciennes, éventuellement limitées à une campagne.\n\n**Scope** : `subsequences:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"parent_campaign","in":"query","required":false,"description":"Limite aux sous-séquences de cette campagne.","schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","required":false,"description":"Filtre sur le nom (contient, sans tenir compte de la casse).","schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Subsequence"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/subsequences?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postSubsequences","tags":["Sous-séquences"],"summary":"Créer une sous-séquence","description":"Crée une sous-séquence active (statut 1) rattachée à `parent_campaign`. Un lead de la campagne y entre quand une condition est remplie (conditions combinées en OU) : passage à un statut d'intérêt de `crm_status`, activité de `lead_activity` (2 ouverture, 4 clic, 91 séquence terminée sans réponse), ou réponse contenant l'un des mots de `reply_contains` (séparés par des virgules, casse ignorée). Le lead entre dans la première sous-séquence active qui correspond.\n\nLe premier email part après le `pre_delay` de la première étape. Sans `subsequence_schedule`, le planning de la campagne parente s'applique. Refus (400) sans aucune condition, (404) si la campagne parente n'est pas dans le workspace.\n\n**Scope** : `subsequences:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubsequenceCreate"},"example":{"parent_campaign":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","name":"Intéressés : proposition de créneau","conditions":{"crm_status":[1],"reply_contains":"intéressé, rappelez-moi"},"sequences":[{"steps":[{"type":"email","pre_delay":1,"pre_delay_unit":"hours","delay":2,"variants":[{"subject":"Re: votre stand au salon","body":"Bonjour {{first_name}}, voici deux créneaux pour en parler…"}]},{"type":"email","delay":0,"variants":[{"subject":"","body":"Bonjour {{first_name}}, un de ces créneaux vous convient-il ?"}]}]}]}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subsequence"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/subsequences\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"parent_campaign\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"name\": \"Intéressés : proposition de créneau\",\n  \"conditions\": {\n    \"crm_status\": [\n      1\n    ],\n    \"reply_contains\": \"intéressé, rappelez-moi\"\n  },\n  \"sequences\": [\n    {\n      \"steps\": [\n        {\n          \"type\": \"email\",\n          \"pre_delay\": 1,\n          \"pre_delay_unit\": \"hours\",\n          \"delay\": 2,\n          \"variants\": [\n            {\n              \"subject\": \"Re: votre stand au salon\",\n              \"body\": \"Bonjour {{first_name}}, voici deux créneaux pour en parler…\"\n            }\n          ]\n        },\n        {\n          \"type\": \"email\",\n          \"delay\": 0,\n          \"variants\": [\n            {\n              \"subject\": \"\",\n              \"body\": \"Bonjour {{first_name}}, un de ces créneaux vous convient-il ?\"\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}'"}]}},"/subsequences/{id}":{"get":{"operationId":"getSubsequencesById","tags":["Sous-séquences"],"summary":"Lire une sous-séquence","description":"Conditions de déclenchement, séquence, planning et limites de la sous-séquence.\n\n**Scope** : `subsequences:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la sous-séquence (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subsequence"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/subsequences/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchSubsequencesById","tags":["Sous-séquences"],"summary":"Modifier une sous-séquence","description":"Met à jour les seuls champs envoyés ; `conditions` et `sequences` remplacent entièrement les anciennes valeurs. La campagne parente ne peut pas changer.\n\n**Scope** : `subsequences:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la sous-séquence (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubsequencePatch"},"example":{"name":"Intéressés : relance rapide","daily_limit_mode":"custom","daily_limit":20}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subsequence"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/subsequences/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Intéressés : relance rapide\",\n  \"daily_limit_mode\": \"custom\",\n  \"daily_limit\": 20\n}'"}]},"delete":{"operationId":"deleteSubsequencesById","tags":["Sous-séquences"],"summary":"Supprimer une sous-séquence","description":"Suppression définitive, avec ses évènements (statistiques). Les leads qui s'y trouvaient restent dans la campagne, détachés de la sous-séquence ; les emails envoyés restent dans l'inbox. Renvoie la sous-séquence telle qu'elle était avant suppression.\n\n**Scope** : `subsequences:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la sous-séquence (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subsequence"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/subsequences/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/subsequences/{id}/pause":{"post":{"operationId":"postSubsequencesByIdPause","tags":["Sous-séquences"],"summary":"Mettre une sous-séquence en pause","description":"Passe une sous-séquence active (statut 1) au statut 2 : plus aucun lead n'y entre et ses envois s'arrêtent. Les leads déjà dedans gardent leur position. Refus (400) si elle n'est pas active.\n\n**Scope** : `subsequences:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la sous-séquence (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subsequence"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/subsequences/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/pause\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/subsequences/{id}/resume":{"post":{"operationId":"postSubsequencesByIdResume","tags":["Sous-séquences"],"summary":"Reprendre une sous-séquence","description":"Repasse une sous-séquence en pause (statut 2) au statut 1 (active) : les leads y entrent de nouveau et les envois reprennent. Refus (400) si elle n'est pas en pause.\n\n**Scope** : `subsequences:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"subsequences:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la sous-séquence (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subsequence"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/subsequences/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/resume\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai/vary":{"post":{"operationId":"postAiVary","tags":["Rédaction IA"],"summary":"Varier un texte avec l'IA","description":"Réécrit un passage d'email : `spintax` le transforme en groupes `{option 1|option 2}` de même sens, `variant` écrit une variante B pour un test A/B. Les `{{variables}}` doivent rester intactes : la sortie est contrôlée et une seconde tentative corrige les erreurs ; celles qui restent sont renvoyées dans `issues`, avec le texte. `context` donne l'email complet quand `text` n'en est qu'une partie. Rien n'est enregistré ; la consommation IA est décomptée du workspace.\n\nRefus (422) si le modèle refuse la demande, 502 si le service IA n'a pas répondu. Renvoie 402 si les crédits IA du mois sont épuisés (ou l'abonnement suspendu), 503 si l'IA n'est pas configurée sur l'instance (`ANTHROPIC_API_KEY` absente).\n\n**Scope** : `campaigns:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"campaigns:update","x-min-role":"member","x-rate-limit":"20/min","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":6000},"context":{"type":"string","maxLength":12000},"mode":{"type":"string","enum":["spintax","variant"]},"variables":{"default":[],"maxItems":200,"type":"array","items":{"type":"string","maxLength":60}},"instructions":{"type":"string","maxLength":500}},"required":["text","mode"]},"example":{"text":"Bonjour {{first_name}}, j'ai vu que {{company_name}} recrutait des commerciaux.","mode":"spintax","variables":["first_name","company_name"]}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Texte proposé."},"issues":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","enum":["unbalanced","empty_option","variable_split","missing_variable","unknown_variable","too_many_combinations"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"description":"Problèmes restants après contrôle (vide si tout est valide)."},"versions":{"type":"array","items":{"type":"string"},"description":"Jusqu'à 5 versions résolues, pour l'aperçu."},"combinations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre de versions possibles du spintax."}},"required":["text","issues","versions","combinations"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai/vary\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"text\": \"Bonjour {{first_name}}, j'\\''ai vu que {{company_name}} recrutait des commerciaux.\",\n  \"mode\": \"spintax\",\n  \"variables\": [\n    \"first_name\",\n    \"company_name\"\n  ]\n}'"}]}},"/ai/spintax-check":{"post":{"operationId":"postAiSpintaxCheck","tags":["Rédaction IA"],"summary":"Contrôler un spintax","description":"Vérifie un texte en spintax sans IA : accolades équilibrées, options vides (seule la dernière option d'un groupe peut être vide, ex. `{Bonjour|}`), variables mal fermées et, si `original` est fourni, variables perdues ou ajoutées. Signale aussi un spintax de plus de 100 000 versions. Renvoie quelques versions résolues pour l'aperçu. Gratuit, rien n'est enregistré.\n\n**Scope** : `campaigns:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"campaigns:read","x-min-role":"viewer","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","maxLength":20000,"description":"Texte en spintax à contrôler (`{option 1|option 2}`)."},"original":{"description":"Texte d'origine. Fourni, il active le contrôle des variables : chaque `{{variable}}` de l'original doit rester présente dans `text`.","type":"string","maxLength":20000},"variables":{"default":[],"description":"Variables connues de la campagne. Avec `original`, une variable de `text` absente de l'original et de cette liste est signalée (`unknown_variable`).","maxItems":200,"type":"array","items":{"type":"string"}}},"required":["text"]},"example":{"text":"{Bonjour|Hello} {{first_name}}, {petite question|une question rapide} pour {{company_name}}.","original":"Bonjour {{first_name}}, petite question pour {{company_name}}."}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"issues":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","enum":["unbalanced","empty_option","variable_split","missing_variable","unknown_variable","too_many_combinations"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"combinations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre de versions possibles (plafonné à 1 000 000)."},"versions":{"type":"array","items":{"type":"string"},"description":"Jusqu'à 5 versions résolues."}},"required":["valid","issues","combinations","versions"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai/spintax-check\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"text\": \"{Bonjour|Hello} {{first_name}}, {petite question|une question rapide} pour {{company_name}}.\",\n  \"original\": \"Bonjour {{first_name}}, petite question pour {{company_name}}.\"\n}'"}]}},"/leads/list":{"post":{"operationId":"postLeadsList","tags":["Leads"],"summary":"Lister les leads","description":"Leads du workspace, filtrés par le corps de la requête (d'où le POST). Pagination par `limit` (1 à 100, défaut 10) et `starting_after` dans le corps ; les leads sont triés par identifiant croissant, donc du plus ancien au plus récent.\n\nFiltres du corps, tous facultatifs et combinés en ET : `campaign` (une campagne), `list_id` (une liste), `in_campaign` / `in_list` (true : seulement les leads en campagne / en liste), `ids`, `excluded_ids`, `contacts` (adresses email exactes), `search` (contient, sur l'email, le prénom, le nom et l'entreprise), `subsequence_id`, `organization_user_ids` (leads attribués à ces membres, champ `assigned_to`) et `filter`. Extensions Replexa : `campaigns` (plusieurs campagnes), `lead_statuses` (statuts de séquence), `interest_statuses` (statuts d'intérêt, `null` pour « Lead »), `replied` et `opened` (au moins une réponse / ouverture, ou aucune) ; les valeurs d'une même liste se combinent en OU.\n\n`filter` accepte une de ces valeurs : `FILTER_VAL_CONTACTED`, `FILTER_VAL_NOT_CONTACTED`, `FILTER_VAL_COMPLETED`, `FILTER_VAL_ACTIVE`, `FILTER_VAL_UNSUBSCRIBED`, `FILTER_VAL_BOUNCED`, `FILTER_VAL_SKIPPED`, `FILTER_VAL_REPLIED`, `FILTER_VAL_OPENED_NO_REPLY`, `FILTER_VAL_COMPLETED_NO_REPLY`, `FILTER_VAL_NO_OPENS` (contactés, jamais ouvert), `FILTER_VAL_LINK_CLICKED`, `FILTER_VAL_IN_SUBSEQUENCE`, `FILTER_VAL_VALID`, `FILTER_VAL_RISKY`, `FILTER_VAL_INVALID` (vérification de l'adresse), `FILTER_LEAD_INTERESTED`, `FILTER_LEAD_NOT_INTERESTED`, `FILTER_LEAD_MEETING_BOOKED`, `FILTER_LEAD_MEETING_COMPLETED`, `FILTER_LEAD_CLOSED`, `FILTER_LEAD_OUT_OF_OFFICE`, `FILTER_LEAD_WRONG_PERSON`, `FILTER_LEAD_LOST`, `FILTER_LEAD_NO_SHOW`, `FILTER_LEAD_CUSTOM_LABEL_POSITIVE` et `FILTER_LEAD_CUSTOM_LABEL_NEGATIVE` (tous les labels personnalisés de cette polarité). Une valeur inconnue est ignorée.\n\n**Scope** : `leads:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"leads:read","x-min-role":"viewer","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"list_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"in_campaign":{"type":"boolean"},"in_list":{"type":"boolean"},"ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"excluded_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"contacts":{"type":"array","items":{"type":"string"}},"search":{"type":"string"},"filter":{"type":"string"},"subsequence_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"organization_user_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"campaigns":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"interest_statuses":{"type":"array","items":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"lead_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"replied":{"type":"boolean"},"opened":{"type":"boolean"},"limit":{"default":10,"type":"integer","minimum":1,"maximum":100},"starting_after":{"type":"string"}}},"example":{"campaign":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","filter":"FILTER_VAL_REPLIED","search":"martin","limit":50}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads/list\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"campaign\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"filter\": \"FILTER_VAL_REPLIED\",\n  \"search\": \"martin\",\n  \"limit\": 50\n}'"}]}},"/leads":{"post":{"operationId":"postLeads","tags":["Leads"],"summary":"Créer un lead","description":"Ajoute un lead à une campagne (`campaign`) ou à une liste (`list_id`) : exactement l'un des deux, sinon 400 ; 404 si la destination n'existe pas dans le workspace. L'adresse est mise en minuscules. Le lead démarre au statut 1 (actif) : dans une campagne active, il reçoit la première étape au prochain créneau du planning. Les `custom_variables` vont dans `payload` et sont déclarées sur la campagne. Un `lt_interest_status` fourni est enregistré tel quel, sans évènement ni webhook ; ce doit être un statut standard ou le code d'un label du workspace (400 sinon).\n\nRenvoie 409 quand le lead n'est pas créé : adresse déjà présente dans la destination (ou ailleurs selon les options `skip_if_*`), ou bloquée par la blocklist. Renvoie 402 quand le quota mensuel de leads du plan est atteint.\n\n**Scope** : `leads:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"company_name":{"type":["string","null"]},"job_title":{"type":["string","null"]},"phone":{"type":["string","null"]},"website":{"type":["string","null"]},"personalization":{"type":["string","null"]},"custom_variables":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["string","number","boolean","null"]}},"lt_interest_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"pl_value_lead":{"type":["string","null"]},"assigned_to":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"campaign":{"description":"Campagne de destination. Indiquez `campaign` ou `list_id`, pas les deux.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"list_id":{"description":"Liste de destination. Indiquez `campaign` ou `list_id`, pas les deux.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"skip_if_in_workspace":{"description":"Ne rien créer si l'adresse existe déjà dans une campagne ou une liste du workspace.","type":"boolean"},"skip_if_in_campaign":{"description":"Ne rien créer si l'adresse est déjà dans une campagne : la campagne de destination, ou n'importe quelle campagne quand la destination est une liste.","type":"boolean"},"skip_if_in_list":{"description":"Ne rien créer si l'adresse est déjà dans une liste : la liste de destination, ou n'importe quelle liste quand la destination est une campagne.","type":"boolean"}},"required":["email"]},"example":{"email":"claire.martin@exemple.fr","first_name":"Claire","last_name":"Martin","company_name":"Atelier Martin","campaign":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","custom_variables":{"ville":"Lyon"},"skip_if_in_workspace":true}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"email\": \"claire.martin@exemple.fr\",\n  \"first_name\": \"Claire\",\n  \"last_name\": \"Martin\",\n  \"company_name\": \"Atelier Martin\",\n  \"campaign\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"custom_variables\": {\n    \"ville\": \"Lyon\"\n  },\n  \"skip_if_in_workspace\": true\n}'"}]},"delete":{"operationId":"deleteLeads","tags":["Leads"],"summary":"Supprimer des leads en masse","description":"Supprime les leads d'une campagne (`campaign_id`) ou d'une liste (`list_id`), au moins l'un des deux (400 sinon), en option restreints à un `status` et/ou à des `ids`. Sans autre filtre, toute la campagne ou toute la liste est vidée, dans la limite de `limit` (10 000 par défaut et au maximum). Comme pour `DELETE /leads/{id}`, les évènements de suivi des leads sont supprimés avec eux. Renvoie le nombre de leads supprimés.\n\n**Scope** : `leads:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:delete","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"campaign_id":{"description":"Campagne dont supprimer les leads (`campaign_id` ou `list_id` requis).","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"list_id":{"description":"Liste dont supprimer les leads (`campaign_id` ou `list_id` requis).","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"description":"Ne supprimer que les leads de ce statut (1 actif, 2 en pause, 3 terminé, -1 bounce, -2 désinscrit, -3 ignoré).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"ids":{"description":"Ne supprimer que ces leads (toujours restreint à la campagne ou à la liste indiquée).","type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"limit":{"description":"Nombre maximum de leads supprimés (défaut et maximum 10 000).","type":"integer","minimum":1,"maximum":10000}}},"example":{"campaign_id":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","status":-1}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads supprimés."}},"required":["count"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/leads\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"campaign_id\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"status\": -1\n}'"}]}},"/leads/add":{"post":{"operationId":"postLeadsAdd","tags":["Leads"],"summary":"Importer des leads en masse","description":"Ajoute jusqu'à 1 000 leads à une campagne (`campaign_id`) ou à une liste (`list_id`), exactement l'un des deux (400 sinon, 404 si la destination n'existe pas). Les adresses sont mises en minuscules. Ne sont pas créés, et sont comptés à part : les emails invalides (`invalid_email_count`), les doublons à l'intérieur de la requête (`duplicate_email_count`), les adresses bloquées par la blocklist (`in_blocklist`) et celles déjà présentes dans la destination, ou ailleurs selon `skip_if_in_workspace`, `skip_if_in_campaign` et `skip_if_in_list` (`duplicated_leads`, repris dans `skipped_count`). Les variables personnalisées rencontrées sont déclarées sur la campagne.\n\nUn `lt_interest_status` qui n'est ni un statut standard ni le code d'un label du workspace fait refuser tout le lot en 400 (le message cite les codes inconnus), avant toute création.\n\nLes leads créés comptent dans le quota mensuel du plan : si l'import le dépasse, rien n'est créé et la requête échoue en 402.\n\n**Scope** : `leads:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"campaign_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"list_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"leads":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"company_name":{"type":["string","null"]},"job_title":{"type":["string","null"]},"phone":{"type":["string","null"]},"website":{"type":["string","null"]},"personalization":{"type":["string","null"]},"custom_variables":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["string","number","boolean","null"]}},"lt_interest_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"pl_value_lead":{"type":["string","null"]},"assigned_to":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["email"]}},"skip_if_in_workspace":{"type":"boolean"},"skip_if_in_campaign":{"type":"boolean"},"skip_if_in_list":{"type":"boolean"}},"required":["leads"]},"example":{"campaign_id":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","skip_if_in_workspace":true,"leads":[{"email":"claire.martin@exemple.fr","first_name":"Claire","company_name":"Atelier Martin","custom_variables":{"ville":"Lyon"}},{"email":"paul.durand@exemple.fr","first_name":"Paul","company_name":"Durand BTP"}]}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"success"},"total_sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads reçus dans la requête."},"leads_uploaded":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads créés."},"in_blocklist":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"duplicated_leads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Adresses déjà présentes (destination ou options `skip_if_*`)."},"skipped_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"invalid_email_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"duplicate_email_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Adresses répétées dans la requête (seule la première est gardée)."},"created_leads":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Position dans le tableau `leads` envoyé."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"}},"required":["index","id","email"],"additionalProperties":false},"description":"Leads créés, avec leur identifiant."}},"required":["status","total_sent","leads_uploaded","in_blocklist","duplicated_leads","skipped_count","invalid_email_count","duplicate_email_count","created_leads"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads/add\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"campaign_id\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"skip_if_in_workspace\": true,\n  \"leads\": [\n    {\n      \"email\": \"claire.martin@exemple.fr\",\n      \"first_name\": \"Claire\",\n      \"company_name\": \"Atelier Martin\",\n      \"custom_variables\": {\n        \"ville\": \"Lyon\"\n      }\n    },\n    {\n      \"email\": \"paul.durand@exemple.fr\",\n      \"first_name\": \"Paul\",\n      \"company_name\": \"Durand BTP\"\n    }\n  ]\n}'"}]}},"/leads/{id}":{"get":{"operationId":"getLeadsById","tags":["Leads"],"summary":"Lire un lead","description":"Fiche complète du lead : coordonnées, variables (`payload`), avancement dans la séquence, compteurs d'ouvertures, de clics et de réponses, statut d'intérêt.\n\n**Scope** : `leads:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"leads:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du lead (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/leads/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchLeadsById","tags":["Leads"],"summary":"Modifier un lead","description":"Modifie les champs envoyés ; l'adresse email ne se modifie pas. `custom_variables` est fusionné avec les variables existantes : une valeur `null` ou une chaîne vide supprime la variable. Changer `lt_interest_status` compte comme un choix manuel (l'IA ne l'écrasera plus) et a les effets décrits pour `POST /leads/update-interest-status` (webhook, arrêt de la séquence, sous-séquence). Un `lt_interest_status` qui n'est ni un statut standard ni le code d'un label du workspace est refusé en 400, sans rien modifier. Renvoie le lead à jour.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du lead (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"company_name":{"type":["string","null"]},"job_title":{"type":["string","null"]},"phone":{"type":["string","null"]},"website":{"type":["string","null"]},"personalization":{"type":["string","null"]},"custom_variables":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["string","number","boolean","null"]}},"lt_interest_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"pl_value_lead":{"type":["string","null"]},"assigned_to":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}}},"example":{"job_title":"Directrice commerciale","custom_variables":{"ville":"Grenoble","ancienne_ville":null},"lt_interest_status":1}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/leads/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"job_title\": \"Directrice commerciale\",\n  \"custom_variables\": {\n    \"ville\": \"Grenoble\",\n    \"ancienne_ville\": null\n  },\n  \"lt_interest_status\": 1\n}'"}]},"delete":{"operationId":"deleteLeadsById","tags":["Leads"],"summary":"Supprimer un lead","description":"Supprime définitivement cette fiche ; les fiches de la même adresse dans d'autres campagnes ou listes restent. Ses évènements de suivi et ses liens CRM sont supprimés avec elle, les emails échangés restent dans l'inbox, détachés du lead. Renvoie le lead tel qu'il était avant suppression.\n\n**Scope** : `leads:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du lead (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/leads/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/leads/{id}/history":{"get":{"operationId":"getLeadsByIdHistory","tags":["Leads"],"summary":"Lire l'historique d'un lead","description":"Toutes les fiches de la même adresse dans le workspace (une par campagne ou liste), de la plus récente à la plus ancienne, avec l'avancement dans chaque campagne, et les 60 derniers évènements de suivi (envois, ouvertures, clics, réponses, bounces, désinscriptions, changements de statut d'intérêt) toutes fiches confondues.\n\n**Scope** : `leads:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"leads:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du lead (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"memberships":{"type":"array","items":{"type":"object","properties":{"lead_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la fiche dans ce conteneur."},"container":{"type":"string","enum":["campaign","list"]},"campaign_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"campaign_name":{"type":["string","null"]},"campaign_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Statut de la campagne (voir `Campaign.status`)."},"list_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"list_name":{"type":["string","null"]},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Statut du lead : 1 actif (en séquence), 2 en pause, 3 terminé, -1 bounce, -2 désinscrit, -3 ignoré."},"progress":{"type":"string","enum":["not_started","in_progress","paused","finished","bounced","unsubscribed","skipped"],"description":"Avancement lisible, déduit du statut et de la date du dernier contact."},"step":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Prochaine étape à envoyer (index à partir de 0)."},"steps_total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre d'étapes de la séquence de la campagne (0 pour une liste)."},"in_subsequence":{"type":"boolean"},"lt_interest_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"opens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"added_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"last_contact_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"last_reply_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["lead_id","container","campaign_id","campaign_name","campaign_status","list_id","list_name","status","progress","step","steps_total","in_subsequence","lt_interest_status","replies","opens","added_at","last_contact_at","last_reply_at"],"additionalProperties":false}},"events":{"type":"array","items":{"type":"object","properties":{"event_type":{"type":"string","description":"`sent`, `opened`, `clicked`, `replied`, `auto_replied`, `bounced`, `unsubscribed` ou `interest_changed`."},"campaign_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"campaign_name":{"type":["string","null"]},"step_index":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"eaccount":{"description":"Boîte d'envoi concernée.","type":["string","null"]},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Détails propres au type d'évènement."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["event_type","campaign_id","campaign_name","step_index","eaccount","data","timestamp_created"],"additionalProperties":false}}},"required":["email","memberships","events"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/leads/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/history\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/leads/move":{"post":{"operationId":"postLeadsMove","tags":["Leads"],"summary":"Déplacer ou copier des leads","description":"Déplace (ou copie avec `copy_leads`) les leads qui correspondent aux filtres vers une campagne (`to_campaign_id`) ou une liste (`to_list_id`), exactement l'une des deux (400 sinon, 404 si elle n'existe pas). Les filtres sont ceux de `POST /leads/list`, dans la limite de `limit` (100 000 par défaut). Au moins un critère de sélection est requis, sinon 400 : `excluded_ids` seul ne suffit pas, et une valeur de `filter` inconnue ne compte pas.\n\nChaque lead traité repart de zéro dans sa destination : statut 1 (actif), étape 0, fil, boîte attitrée et sous-séquence effacés. Son statut d'intérêt est gardé, sauf avec `reset_interest_status`. Une copie crée de nouveaux leads (avec leurs variables et compteurs) et compte dans le quota mensuel du plan (402 s'il est dépassé).\n\nPar défaut, les adresses déjà présentes dans la destination sont ignorées et comptées dans `skipped`, de même que la deuxième occurrence d'une adresse sélectionnée deux fois. Avec `check_duplicates: false`, un doublon interrompt le traitement en 409 : le lot de 500 leads qui le contient n'est pas traité, les lots précédents restent déplacés. Le traitement est synchrone : préférez des lots de quelques milliers.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"list_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"in_campaign":{"type":"boolean"},"in_list":{"type":"boolean"},"ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"excluded_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"contacts":{"type":"array","items":{"type":"string"}},"search":{"type":"string"},"filter":{"type":"string"},"subsequence_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"organization_user_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"campaigns":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"interest_statuses":{"type":"array","items":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"lead_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"replied":{"type":"boolean"},"opened":{"type":"boolean"},"to_campaign_id":{"description":"Campagne de destination. Indiquez `to_campaign_id` ou `to_list_id`, pas les deux.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"to_list_id":{"description":"Liste de destination. Indiquez `to_campaign_id` ou `to_list_id`, pas les deux.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"copy_leads":{"description":"true : copie les leads (les originaux restent en place et les copies comptent dans le quota mensuel). Défaut : déplacement.","type":"boolean"},"check_duplicates":{"description":"Ignore les leads dont l'adresse est déjà dans la destination (défaut true). Avec false, un doublon fait échouer la requête en 409.","type":"boolean"},"reset_interest_status":{"description":"Remet aussi le statut d'intérêt à null (« Lead ») et réautorise l'étiquetage automatique par l'IA.","type":"boolean"},"limit":{"description":"Nombre maximum de leads traités (défaut et maximum 100 000).","type":"integer","minimum":1,"maximum":100000}}},"example":{"campaign":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","filter":"FILTER_VAL_COMPLETED_NO_REPLY","to_list_id":"0193f0a2-8a3b-7c2d-9e4f-5a6b7c8d9e0f"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"success"},"moved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads déplacés (ou copiés)."},"skipped":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads ignorés car déjà présents dans la destination."}},"required":["status","moved","skipped"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads/move\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"campaign\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"filter\": \"FILTER_VAL_COMPLETED_NO_REPLY\",\n  \"to_list_id\": \"0193f0a2-8a3b-7c2d-9e4f-5a6b7c8d9e0f\"\n}'"}]}},"/leads/update-interest-status":{"post":{"operationId":"postLeadsUpdateInterestStatus","tags":["Leads"],"summary":"Changer le statut d'intérêt d'un lead","description":"Applique `interest_value` à toutes les fiches de l'adresse `lead_email` dans le workspace, ou seulement à celles de `campaign_id` / `list_id`. 404 si aucune fiche ne correspond ; 400 si `interest_value` n'est ni un statut standard ni le code d'un label du workspace. `null` = « Lead » (aucun statut). Statuts standards : 1 intéressé, 2 RDV pris, 3 RDV effectué, 4 gagné, 0 absent (out of office), -1 pas intéressé, -2 mauvais interlocuteur, -3 perdu, -4 absent au RDV. Labels personnalisés (`GET /lead-labels`) : 50 à 30000 positifs, -50 à -500 négatifs, -501 à -30000 neutres.\n\nChanger le statut d'intérêt déclenche l'évènement `interest_changed` et le webhook correspondant (`lead_interested`, `lead_meeting_booked`, `lead_not_interested`…, ou `custom_interest_value` plus `custom_label_any_positive` / `custom_label_any_negative` pour un label personnalisé), arrêt de la séquence (statut 3) pour tout statut autre que 0 « absent » quand le lead était actif, et entrée dans la sous-séquence de la campagne dont la condition `crm_status` correspond. Remettre `null` ne déclenche ni évènement ni webhook.\n\nPar défaut (`disable_auto_interest` absent ou true), le statut compte comme posé à la main et l'IA ne le modifiera plus. Avec `disable_auto_interest: false`, les fiches dont le statut a déjà été posé à la main ne sont pas modifiées (elles restent comptées dans `count`). `ai_interest_value` est accepté mais sans effet ici.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lead_email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"campaign_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"list_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"ai_interest_value":{"type":"number"},"disable_auto_interest":{"type":"boolean"}},"required":["lead_email","interest_value"]},"example":{"lead_email":"claire.martin@exemple.fr","interest_value":2,"campaign_id":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","const":"Interest status updated"},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Fiches traitées."}},"required":["message","count"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads/update-interest-status\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"lead_email\": \"claire.martin@exemple.fr\",\n  \"interest_value\": 2,\n  \"campaign_id\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\"\n}'"}]}},"/leads/subsequence/move":{"post":{"operationId":"postLeadsSubsequenceMove","tags":["Leads"],"summary":"Faire entrer un lead dans une sous-séquence","description":"Place le lead dans la sous-séquence : son statut repasse à 1 (actif) et la première étape de la sous-séquence part après son délai d'attente (`pre_delay`). Si le lead était dans une autre sous-séquence, il la quitte. 404 si le lead ou la sous-séquence n'existe pas dans le workspace ; 400 si le lead n'est pas dans une campagne (lead de liste) ou si la sous-séquence appartient à une autre campagne que la sienne.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du lead."},"subsequence_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Sous-séquence à démarrer pour ce lead."}},"required":["id","subsequence_id"]},"example":{"id":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","subsequence_id":"0193f0a2-8a3b-7c2d-9e4f-5a6b7c8d9e0f"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads/subsequence/move\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"id\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"subsequence_id\": \"0193f0a2-8a3b-7c2d-9e4f-5a6b7c8d9e0f\"\n}'"}]}},"/leads/subsequence/remove":{"post":{"operationId":"postLeadsSubsequenceRemove","tags":["Leads"],"summary":"Sortir un lead de sa sous-séquence","description":"Retire le lead de sa sous-séquence et arrête ses envois : il passe au statut 3 (terminé) et ne reprend pas la séquence principale. 400 si le lead n'est dans aucune sous-séquence (rien n'est modifié), 404 s'il n'existe pas dans le workspace.\n\n**Scope** : `leads:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"leads:update","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du lead."}},"required":["id"]},"example":{"id":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/leads/subsequence/remove\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"id\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\"\n}'"}]}},"/lead-lists":{"get":{"operationId":"getLeadLists","tags":["Listes de leads"],"summary":"Lister les listes de leads","description":"Listes du workspace, des plus récentes aux plus anciennes.\n\n**Scope** : `lead_lists:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"lead_lists:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Filtre sur le nom (contient, sans tenir compte de la casse).","schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LeadList"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/lead-lists?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postLeadLists","tags":["Listes de leads"],"summary":"Créer une liste de leads","description":"Crée une liste vide. Ajoutez-y des leads avec `POST /leads` ou `POST /leads/add` (champ `list_id`), ou déplacez-en avec `POST /leads/move`.\n\n**Scope** : `lead_lists:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"lead_lists:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListWrite"},"example":{"name":"Salon Batimat 2026"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadList"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/lead-lists\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Salon Batimat 2026\"\n}'"}]}},"/lead-lists/{id}":{"get":{"operationId":"getLeadListsById","tags":["Listes de leads"],"summary":"Lire une liste de leads","description":"Nom et date de création de la liste. Ses leads s'obtiennent avec `POST /leads/list` et le filtre `list_id`.\n\n**Scope** : `lead_lists:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"lead_lists:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la liste (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadList"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/lead-lists/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchLeadListsById","tags":["Listes de leads"],"summary":"Renommer une liste de leads","description":"Change le nom de la liste et renvoie la liste à jour.\n\n**Scope** : `lead_lists:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"lead_lists:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la liste (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListWrite"},"example":{"name":"Salon Batimat 2026, relancés"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadList"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/lead-lists/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Salon Batimat 2026, relancés\"\n}'"}]},"delete":{"operationId":"deleteLeadListsById","tags":["Listes de leads"],"summary":"Supprimer une liste de leads","description":"Supprime la liste **et tous les leads qu'elle contient**, avec leurs évènements de suivi ; les emails déjà échangés restent dans l'inbox. Pour garder les leads, déplacez-les d'abord avec `POST /leads/move`. Renvoie la liste supprimée.\n\n**Scope** : `lead_lists:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"lead_lists:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la liste (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadList"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/lead-lists/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/lead-labels":{"get":{"operationId":"getLeadLabels","tags":["Labels et tags"],"summary":"Lister les labels de leads","description":"Statuts d'intérêt personnalisés du workspace, des plus récents aux plus anciens. Les statuts standards (intéressé, RDV pris…) ne sont pas listés : leurs codes sont fixes. `null` = « Lead » (aucun statut). Statuts standards : 1 intéressé, 2 RDV pris, 3 RDV effectué, 4 gagné, 0 absent (out of office), -1 pas intéressé, -2 mauvais interlocuteur, -3 perdu, -4 absent au RDV. Labels personnalisés (`GET /lead-labels`) : 50 à 30000 positifs, -50 à -500 négatifs, -501 à -30000 neutres.\n\n**Scope** : `lead-labels:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"lead-labels:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Filtre sur le nom du label (contient, sans tenir compte de la casse).","schema":{"type":"string"}},{"name":"interest_status","in":"query","required":false,"description":"Polarité du label.","schema":{"type":"string","enum":["positive","negative","neutral"]}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LeadLabel"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/lead-labels?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postLeadLabels","tags":["Labels et tags"],"summary":"Créer un label de leads","description":"Crée un statut d'intérêt personnalisé. Son code numérique (`interest_status`) est attribué automatiquement : le premier libre à partir de 50 pour un label positif, de -50 pour un négatif, de -501 pour un neutre. Ce code s'utilise ensuite comme `lt_interest_status` ou `interest_value`. Avec `use_with_ai` (true par défaut), l'IA peut l'attribuer en classant les réponses reçues, d'après sa `description`. 409 si un label du même nom existe déjà.\n\n**Scope** : `lead-labels:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"lead-labels:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1},"interest_status_label":{"type":"string","enum":["positive","negative","neutral"]},"description":{"type":["string","null"]},"use_with_ai":{"type":"boolean"}},"required":["label","interest_status_label"]},"example":{"label":"Demande de devis","interest_status_label":"positive","description":"Le prospect demande un prix ou un devis chiffré.","use_with_ai":true}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadLabel"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/lead-labels\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"label\": \"Demande de devis\",\n  \"interest_status_label\": \"positive\",\n  \"description\": \"Le prospect demande un prix ou un devis chiffré.\",\n  \"use_with_ai\": true\n}'"}]}},"/lead-labels/{id}":{"get":{"operationId":"getLeadLabelsById","tags":["Labels et tags"],"summary":"Lire un label de leads","description":"Nom, polarité, code numérique et réglages IA du label.\n\n**Scope** : `lead-labels:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"lead-labels:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du label (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadLabel"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/lead-labels/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchLeadLabelsById","tags":["Labels et tags"],"summary":"Modifier un label de leads","description":"Modifie le nom, la description ou `use_with_ai`. La polarité et le code numérique ne changent pas : les leads qui portent le label le gardent. 409 si le nouveau nom est déjà pris.\n\n**Scope** : `lead-labels:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"lead-labels:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du label (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"description":"Nom affiché du label (unique dans le workspace).","type":"string","minLength":1},"description":{"description":"Description, transmise à l'IA pour reconnaître les réponses qui correspondent au label.","type":["string","null"]},"use_with_ai":{"description":"L'IA peut attribuer ce label en classant les réponses reçues.","type":"boolean"}}},"example":{"description":"Le prospect demande un prix, un devis ou une grille tarifaire.","use_with_ai":true}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadLabel"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/lead-labels/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"description\": \"Le prospect demande un prix, un devis ou une grille tarifaire.\",\n  \"use_with_ai\": true\n}'"}]},"delete":{"operationId":"deleteLeadLabelsById","tags":["Labels et tags"],"summary":"Supprimer un label de leads","description":"Supprime le label. Les leads qui le portaient reçoivent le statut `reassigned_status`, ou `null` (« Lead ») sans ce paramètre. `reassigned_status` doit être un entier : un statut standard ou le code d'un autre label du workspace (400 sinon, label conservé). Cette réaffectation est directe : elle ne déclenche ni évènement, ni webhook, ni sous-séquence, et ne change pas le statut de séquence des leads. Si elle échoue, le label n'est pas supprimé. Renvoie le label supprimé.\n\n**Scope** : `lead-labels:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"lead-labels:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du label (UUID).","schema":{"type":"string","format":"uuid"}},{"name":"reassigned_status","in":"query","required":false,"description":"Statut d'intérêt à donner aux leads qui portaient ce label (code standard ou d'un autre label).","schema":{"type":"integer"},"example":-1}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadLabel"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/lead-labels/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90?reassigned_status=-1\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/lead-labels/ai-reply-label":{"post":{"operationId":"postLeadLabelsAiReplyLabel","tags":["Labels et tags"],"summary":"Tester la classification IA d'une réponse","description":"Classe un texte de réponse comme le fait l'IA sur les réponses reçues, parmi les statuts standards et les labels personnalisés `use_with_ai` du workspace. Rien n'est enregistré, mais l'appel consomme des crédits IA : 402 quand ceux du mois sont épuisés, 422 si le modèle refuse de classer le texte, 503 si l'IA n'est pas configurée sur l'instance.\n\n**Scope** : `lead-labels:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"lead-labels:read","x-min-role":"viewer","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reply_text":{"type":"string","minLength":1,"description":"Texte de la réponse reçue (8 000 caractères au plus sont analysés)."}},"required":["reply_text"]},"example":{"reply_text":"Bonjour, pouvez-vous m'envoyer un devis pour trois boîtes d'envoi ? Merci."}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string","description":"Clé du label choisi : `interested`, `meeting_booked`, `out_of_office`, `not_interested`, `wrong_person`, `neutral` ou `custom_<code>`."},"interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Statut d'intérêt correspondant (null pour `neutral`)."},"confidence":{"type":"number","description":"Confiance du modèle, de 0 à 1."},"is_auto_reply":{"type":"boolean"},"unsubscribe_request":{"type":"boolean","description":"La personne demande à ne plus être contactée."},"reason":{"type":"string","description":"Justification courte, en français."},"custom_labels_considered":{"type":"array","items":{"type":"string"},"description":"Noms des labels personnalisés proposés au modèle."}},"required":["result","interest_value","confidence","is_auto_reply","unsubscribe_request","reason","custom_labels_considered"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"503":{"$ref":"#/components/responses/E503"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/lead-labels/ai-reply-label\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"reply_text\": \"Bonjour, pouvez-vous m'\\''envoyer un devis pour trois boîtes d'\\''envoi ? Merci.\"\n}'"}]}},"/custom-tags":{"get":{"operationId":"getCustomTags","tags":["Labels et tags"],"summary":"Lister les tags de boîtes d'envoi","description":"Tags posés sur les boîtes d'envoi (champ `tags` d'une boîte), triés par nom. Une campagne peut envoyer depuis toutes les boîtes d'un tag avec `email_tag_list`. Ils ne s'appliquent pas aux leads : pour qualifier un lead, voir les labels de leads.\n\n**Scope** : `custom_tags:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"custom_tags:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CustomTag"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/custom-tags\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postCustomTags","tags":["Labels et tags"],"summary":"Créer un tag de boîtes d'envoi","description":"Crée un tag à poser ensuite sur des boîtes d'envoi (champ `tags`, liste d'identifiants de tags). 409 si un tag du même nom existe déjà.\n\n**Scope** : `custom_tags:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"custom_tags:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":60,"description":"Nom du tag (60 caractères au plus, unique dans le workspace)."},"description":{"type":["string","null"]}},"required":["label"]},"example":{"label":"Domaine secondaire","description":"Boîtes sur exemple-mail.fr"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomTag"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/custom-tags\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"label\": \"Domaine secondaire\",\n  \"description\": \"Boîtes sur exemple-mail.fr\"\n}'"}]}},"/custom-tags/{id}":{"delete":{"operationId":"deleteCustomTagsById","tags":["Labels et tags"],"summary":"Supprimer un tag de boîtes d'envoi","description":"Supprime le tag et le retire des boîtes d'envoi (`tags`) et des campagnes (`email_tag_list`) qui l'utilisaient : une campagne qui n'envoyait que par ce tag n'a plus de boîte par ce biais. Renvoie le tag supprimé.\n\n**Scope** : `custom_tags:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"custom_tags:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du tag (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomTag"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/custom-tags/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/block-lists-entries":{"get":{"operationId":"getBlockListsEntries","tags":["Blocklist"],"summary":"Lister la blocklist","description":"Emails et domaines bloqués du workspace, des plus récents aux plus anciens. Les désinscriptions y sont ajoutées automatiquement, avec leur origine dans `reason`.\n\n**Scope** : `block_list_entries:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"block_list_entries:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Filtre sur la valeur (contient, sans tenir compte de la casse).","schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BlocklistEntry"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/block-lists-entries?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postBlockListsEntries","tags":["Blocklist"],"summary":"Ajouter à la blocklist","description":"Bloque une adresse email ou un domaine entier (valeur sans @). Les valeurs sont mises en minuscules et dédoublonnées ; une valeur déjà présente est ignorée sans erreur. Les adresses bloquées ne sont plus importées (`in_blocklist` de `POST /leads/add`), et les leads déjà en campagne qu'elles concernent passent au statut -3 (ignoré) au lieu de recevoir leur prochain email.\n\nAvec `bl_value` seul, renvoie l'entrée, créée ou déjà présente. Avec `bl_values`, renvoie `{ items, count }` : les entrées réellement créées. 400 si le corps ne contient aucune valeur (ni `bl_value`, ni `bl_values` non vide).\n\n**Scope** : `block_list_entries:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"block_list_entries:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bl_value":{"description":"Adresse email (`nom@domaine.fr`) ou domaine (`domaine.fr`), mis en minuscules. Une valeur sans @ est un domaine.","type":"string","minLength":3},"bl_values":{"description":"Ajout en masse, 10 000 valeurs au plus.","maxItems":10000,"type":"array","items":{"description":"Adresse email (`nom@domaine.fr`) ou domaine (`domaine.fr`), mis en minuscules. Une valeur sans @ est un domaine.","type":"string","minLength":3}}}},"example":{"bl_values":["concurrent.fr","jean.dupont@exemple.fr"]}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'entrée."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"bl_value":{"type":"string","description":"Adresse email ou domaine bloqué, en minuscules."},"is_domain":{"type":"boolean","description":"true : tout le domaine est bloqué."},"reason":{"description":"Origine : null pour un ajout manuel, texte libre pour une désinscription automatique (lien de désinscription, demande dans une réponse).","type":["string","null"]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date d'ajout."}},"required":["id","organization_id","bl_value","is_domain","reason","timestamp_created"],"additionalProperties":false},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'entrée."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"bl_value":{"type":"string","description":"Adresse email ou domaine bloqué, en minuscules."},"is_domain":{"type":"boolean","description":"true : tout le domaine est bloqué."},"reason":{"description":"Origine : null pour un ajout manuel, texte libre pour une désinscription automatique (lien de désinscription, demande dans une réponse).","type":["string","null"]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date d'ajout."}},"required":["id","organization_id","bl_value","is_domain","reason","timestamp_created"],"additionalProperties":false}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Entrées créées."}},"required":["items","count"],"additionalProperties":false}]}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/block-lists-entries\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"bl_values\": [\n    \"concurrent.fr\",\n    \"jean.dupont@exemple.fr\"\n  ]\n}'"}]}},"/block-lists-entries/{id}":{"get":{"operationId":"getBlockListsEntriesById","tags":["Blocklist"],"summary":"Lire une entrée de la blocklist","description":"Valeur bloquée, type (adresse ou domaine) et origine de l'entrée.\n\n**Scope** : `block_list_entries:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"block_list_entries:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'entrée (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlocklistEntry"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/block-lists-entries/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"delete":{"operationId":"deleteBlockListsEntriesById","tags":["Blocklist"],"summary":"Retirer une entrée de la blocklist","description":"Débloque l'adresse ou le domaine pour les prochains imports et envois. Les leads déjà passés au statut -2 (désinscrit) ou -3 (ignoré) le gardent : réimportez-les ou déplacez-les (`POST /leads/move`) pour les relancer. Renvoie l'entrée supprimée.\n\n**Scope** : `block_list_entries:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"block_list_entries:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'entrée (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlocklistEntry"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/block-lists-entries/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/accounts":{"get":{"operationId":"getAccounts","tags":["Boîtes d'envoi"],"summary":"Lister les boîtes d'envoi","description":"Boîtes SMTP/IMAP et OAuth (Google, Microsoft) du workspace, des plus récentes aux plus anciennes. Les mots de passe et les jetons OAuth ne sont jamais renvoyés.\n\n**Scope** : `accounts:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"accounts:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Filtre sur l'adresse (contient, sans tenir compte de la casse).","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Statut exact : 1 active, 2 en pause, 3 maintenance, -1 erreur de connexion, -2 soft bounce, -3 erreur d'envoi.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/accounts?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postAccounts","tags":["Boîtes d'envoi"],"summary":"Ajouter une boîte SMTP/IMAP","description":"Ajoute une boîte avec mot de passe (`auth_type: \"password\"`). Les connexions SMTP et IMAP sont testées avant l'enregistrement : un échec renvoie 400 avec le message du serveur (`Connexion SMTP impossible : …`). Passez `skip_check=true` pour enregistrer sans tester.\n\nLes mots de passe sont chiffrés et ne sont jamais renvoyés. Sans `smtp_secure`, le TLS implicite n'est activé que pour le port 465. L'adresse est enregistrée en minuscules ; une adresse déjà présente dans le workspace renvoie 409, un tag inconnu 400.\n\nLes boîtes Google et Microsoft se connectent par OAuth depuis l'interface (Boîtes d'envoi › Ajouter), pas par l'API.\n\nRenvoie 402 quand le plan ne permet pas une boîte de plus.\n\n**Scope** : `accounts:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"accounts:create","x-min-role":"member","parameters":[{"name":"skip_check","in":"query","required":false,"description":"true : enregistre la boîte sans tester SMTP ni IMAP.","schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountCreate"},"example":{"email":"jeanne@exemple.fr","first_name":"Jeanne","last_name":"Martin","smtp_host":"smtp.exemple.fr","smtp_port":587,"smtp_username":"jeanne@exemple.fr","smtp_password":"mot-de-passe-smtp","imap_host":"imap.exemple.fr","imap_port":993,"imap_username":"jeanne@exemple.fr","imap_password":"mot-de-passe-imap","daily_limit":40,"sending_gap":12,"signature":"<p>Jeanne Martin<br />Exemple SARL</p>"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/accounts\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"email\": \"jeanne@exemple.fr\",\n  \"first_name\": \"Jeanne\",\n  \"last_name\": \"Martin\",\n  \"smtp_host\": \"smtp.exemple.fr\",\n  \"smtp_port\": 587,\n  \"smtp_username\": \"jeanne@exemple.fr\",\n  \"smtp_password\": \"mot-de-passe-smtp\",\n  \"imap_host\": \"imap.exemple.fr\",\n  \"imap_port\": 993,\n  \"imap_username\": \"jeanne@exemple.fr\",\n  \"imap_password\": \"mot-de-passe-imap\",\n  \"daily_limit\": 40,\n  \"sending_gap\": 12,\n  \"signature\": \"<p>Jeanne Martin<br />Exemple SARL</p>\"\n}'"}]}},"/accounts/{email}":{"get":{"operationId":"getAccountsByEmail","tags":["Boîtes d'envoi"],"summary":"Lire une boîte d'envoi","description":"Réglages et état de la boîte : statut, dernière erreur, dernier envoi, connexion OAuth. Les secrets ne sont jamais renvoyés.\n\n**Scope** : `accounts:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"accounts:read","x-min-role":"viewer","parameters":[{"name":"email","in":"path","required":true,"description":"Adresse de la boîte d'envoi (encodée dans l'URL).","schema":{"type":"string","format":"email"},"example":"jeanne@exemple.fr"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/accounts/jeanne%40exemple.fr\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchAccountsByEmail","tags":["Boîtes d'envoi"],"summary":"Modifier une boîte d'envoi","description":"Modifie les champs envoyés, les autres restent inchangés. L'adresse ne se modifie pas et les connexions ne sont pas retestées.\n\nBoîte SMTP/IMAP : changer `smtp_host`, `smtp_port` ou `smtp_username` exige de renvoyer `smtp_password` (de même `imap_password` pour les champs IMAP), sinon 400. Un mot de passe envoyé seul remplace l'ancien.\n\nBoîte OAuth (`auth_type` `oauth_google` ou `oauth_microsoft`) : les mots de passe et les champs serveur (`smtp_host`, `smtp_port`, `smtp_username`, `smtp_secure`, `imap_host`, `imap_port`, `imap_username`) sont refusés avec 400 dès qu'ils diffèrent de la valeur enregistrée, car Google ou Microsoft les gèrent ; de même pour `provider_code`, fixé par le fournisseur (2 Google, 3 Microsoft). Pour passer au mot de passe, supprimez la boîte puis ajoutez-la en SMTP/IMAP. Les autres champs (nom, limites, signature, tags…) se modifient normalement.\n\n**Scope** : `accounts:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"accounts:update","x-min-role":"member","parameters":[{"name":"email","in":"path","required":true,"description":"Adresse de la boîte d'envoi (encodée dans l'URL).","schema":{"type":"string","format":"email"},"example":"jeanne@exemple.fr"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPatch"},"example":{"daily_limit":50,"sending_gap":15,"signature":"<p>Jeanne Martin<br />Exemple SARL</p>"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/accounts/jeanne%40exemple.fr\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"daily_limit\": 50,\n  \"sending_gap\": 15,\n  \"signature\": \"<p>Jeanne Martin<br />Exemple SARL</p>\"\n}'"}]},"delete":{"operationId":"deleteAccountsByEmail","tags":["Boîtes d'envoi"],"summary":"Supprimer une boîte d'envoi","description":"Retire définitivement la boîte et renvoie son dernier état. Boîte Google : l'accès OAuth est d'abord révoqué chez Google (`oauth_revoked`). Boîte Microsoft : les jetons sont effacés de Replexa, l'application se retire sur myapps.microsoft.com. La déconnexion OAuth est inscrite au journal d'audit.\n\nLes emails déjà envoyés ou reçus restent dans l'inbox. L'adresse est retirée de `email_list` des campagnes du workspace qui la citaient ; les campagnes qui ciblent la boîte par un tag (`email_tag_list`) ne changent pas.\n\n**Scope** : `accounts:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"accounts:delete","x-min-role":"member","parameters":[{"name":"email","in":"path","required":true,"description":"Adresse de la boîte d'envoi (encodée dans l'URL).","schema":{"type":"string","format":"email"},"example":"jeanne@exemple.fr"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDeleted"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/accounts/jeanne%40exemple.fr\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/accounts/{email}/pause":{"post":{"operationId":"postAccountsByEmailPause","tags":["Boîtes d'envoi"],"summary":"Mettre une boîte en pause","description":"Passe la boîte au statut 2 (en pause) : elle n'envoie plus d'emails de campagne jusqu'à `POST /accounts/{email}/resume`, mais ses réponses continuent d'être relevées. Renvoie la boîte modifiée.\n\n**Scope** : `accounts:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"accounts:update","x-min-role":"member","parameters":[{"name":"email","in":"path","required":true,"description":"Adresse de la boîte d'envoi (encodée dans l'URL).","schema":{"type":"string","format":"email"},"example":"jeanne@exemple.fr"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/accounts/jeanne%40exemple.fr/pause\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/accounts/{email}/resume":{"post":{"operationId":"postAccountsByEmailResume","tags":["Boîtes d'envoi"],"summary":"Réactiver une boîte","description":"Repasse la boîte au statut 1 (active) et efface `status_message`, qu'elle soit en pause ou en erreur. La connexion n'est pas retestée : vérifiez-la avec `POST /accounts/test/vitals`. Renvoie la boîte modifiée.\n\nUne boîte OAuth à reconnecter (`status_message.code` `OAUTH_RECONNECT`) est refusée avec 400 : l'accès Google ou Microsoft a été retiré ou a expiré, seule une reconnexion depuis l'interface la répare.\n\n**Scope** : `accounts:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"accounts:update","x-min-role":"member","parameters":[{"name":"email","in":"path","required":true,"description":"Adresse de la boîte d'envoi (encodée dans l'URL).","schema":{"type":"string","format":"email"},"example":"jeanne@exemple.fr"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/accounts/jeanne%40exemple.fr/resume\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/accounts/analytics/daily":{"get":{"operationId":"getAccountsAnalyticsDaily","tags":["Boîtes d'envoi"],"summary":"Statistiques quotidiennes des boîtes","description":"Emails envoyés, réponses et bounces par jour (UTC) et par boîte, sur les `days` derniers jours, aujourd'hui compris. Seuls les couples boîte et jour qui ont au moins un évènement apparaissent. La réponse est un tableau trié par date croissante (pas d'objet `items`). Tous les évènements de la période sont comptés.\n\n**Scope** : `accounts:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"accounts:read","x-min-role":"viewer","parameters":[{"name":"emails","in":"query","required":false,"description":"Boîtes à inclure, séparées par des virgules. Absent : toutes les boîtes.","schema":{"type":"string"},"example":"jeanne@exemple.fr"},{"name":"days","in":"query","required":false,"description":"Nombre de jours, de 1 à 90 (défaut 7).","schema":{"type":"integer"},"example":7}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"Jour (UTC)."},"email_account":{"type":"string","description":"Adresse de la boîte."},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"replies":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"bounced":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["date","email_account","sent","replies","bounced"],"additionalProperties":false}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/accounts/analytics/daily?emails=jeanne%40exemple.fr&days=7\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/accounts/bulk":{"post":{"operationId":"postAccountsBulk","tags":["Boîtes d'envoi"],"summary":"Importer des boîtes en masse","description":"Ajoute jusqu'à 500 boîtes SMTP/IMAP en une requête (une entrée par boîte, avec ses réglages SMTP et IMAP). Chaque boîte est traitée séparément : une erreur n'arrête pas l'import, elle est signalée dans `items`.\n\n- Une boîte déjà présente est ignorée (`skipped`), ou mise à jour et remise au statut actif avec `update_existing: true`.\n- Un seul mot de passe suffit : il sert pour SMTP et IMAP. Sans aucun mot de passe, la ligne est en erreur.\n- Avec `test: true` (défaut), SMTP et IMAP sont testés et une boîte qui échoue n'est pas importée.\n\nLe quota de boîtes du plan est vérifié avant l'import, pour les seules nouvelles adresses : s'il est dépassé, rien n'est importé et la réponse est 402.\n\n**Scope** : `accounts:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"accounts:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"default":"","type":"string"},"last_name":{"default":"","type":"string"},"provider_code":{"default":1,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"smtp_port":{"default":587,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_username":{"type":"string","minLength":1},"smtp_password":{"default":"","type":"string"},"smtp_secure":{"type":"boolean"},"imap_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"imap_port":{"default":993,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"imap_username":{"type":"string","minLength":1},"imap_password":{"default":"","type":"string"},"daily_limit":{"default":30,"type":"integer","minimum":1,"maximum":9007199254740991},"sending_gap":{"default":10,"type":"integer","minimum":0,"maximum":1440},"enable_slow_ramp":{"type":"boolean"},"signature":{"type":["string","null"]},"reply_to":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"tracking_domain_name":{"anyOf":[{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"warmup":{"type":"object","properties":{"enabled":{"type":"boolean"},"limit":{"type":"integer","minimum":1,"maximum":200},"increment":{"type":"integer","minimum":0,"maximum":4},"reply_rate":{"type":"number","minimum":0,"maximum":100},"slow_warmup_disabled":{"type":"boolean"},"filter_tag":{"type":["string","null"]},"advanced":{"type":"object","properties":{"weekday_only":{"type":"boolean"},"read_emulation":{"type":"boolean"},"warm_ctd":{"type":"boolean"},"open_rate":{"type":"number","minimum":0,"maximum":100},"spam_save_rate":{"type":"number","minimum":0,"maximum":100},"important_rate":{"type":"number","minimum":0,"maximum":100}},"required":["weekday_only","read_emulation","warm_ctd","open_rate","spam_save_rate","important_rate"]}}},"inbox_placement_test_limit":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["email","smtp_host","smtp_username","imap_host","imap_username"]},"description":"Boîtes à importer, de 1 à 500. Un seul mot de passe suffit : il sert alors pour SMTP et IMAP."},"test":{"default":true,"description":"Teste SMTP et IMAP avant d'enregistrer (une boîte qui échoue n'est pas importée).","type":"boolean"},"update_existing":{"default":false,"description":"Met à jour les boîtes déjà présentes (sinon elles sont ignorées).","type":"boolean"}},"required":["accounts"]},"example":{"accounts":[{"email":"jeanne@exemple.fr","first_name":"Jeanne","last_name":"Martin","smtp_host":"smtp.exemple.fr","smtp_port":587,"smtp_username":"jeanne@exemple.fr","smtp_password":"mot-de-passe","imap_host":"imap.exemple.fr","imap_port":993,"imap_username":"jeanne@exemple.fr","daily_limit":40}],"test":true,"update_existing":false}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"skipped":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"errors":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"items":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"status":{"type":"string","enum":["created","updated","skipped","error"]},"error":{"description":"Raison de l'erreur ou de l'abandon (connexion refusée, mot de passe manquant, « Déjà présente »).","type":"string"}},"required":["email","status"],"additionalProperties":false}}},"required":["created","updated","skipped","errors","items"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/accounts/bulk\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"accounts\": [\n    {\n      \"email\": \"jeanne@exemple.fr\",\n      \"first_name\": \"Jeanne\",\n      \"last_name\": \"Martin\",\n      \"smtp_host\": \"smtp.exemple.fr\",\n      \"smtp_port\": 587,\n      \"smtp_username\": \"jeanne@exemple.fr\",\n      \"smtp_password\": \"mot-de-passe\",\n      \"imap_host\": \"imap.exemple.fr\",\n      \"imap_port\": 993,\n      \"imap_username\": \"jeanne@exemple.fr\",\n      \"daily_limit\": 40\n    }\n  ],\n  \"test\": true,\n  \"update_existing\": false\n}'"}]}},"/accounts/test/vitals":{"post":{"operationId":"postAccountsTestVitals","tags":["Boîtes d'envoi"],"summary":"Tester les connexions des boîtes","description":"Ouvre une connexion SMTP et une connexion IMAP pour chaque boîte demandée (toutes si `accounts` est absent ou vide) et renvoie le résultat. Aucun email n'est envoyé et le statut des boîtes ne change pas. Les adresses inconnues sont ignorées.\n\n**Scope** : `accounts:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"accounts:update","x-min-role":"member","x-rate-limit":"20/min","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"description":"Adresses des boîtes à tester. Absent ou vide : toutes les boîtes du workspace.","type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}}}},"example":{"accounts":["jeanne@exemple.fr"]}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"smtp_ok":{"type":"boolean"},"smtp_error":{"type":["string","null"]},"imap_ok":{"type":"boolean"},"imap_error":{"type":["string","null"]}},"required":["email","smtp_ok","smtp_error","imap_ok","imap_error"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/accounts/test/vitals\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"accounts\": [\n    \"jeanne@exemple.fr\"\n  ]\n}'"}]}},"/account-campaign-mappings/{email}":{"get":{"operationId":"getAccountCampaignMappingsByEmail","tags":["Boîtes d'envoi"],"summary":"Lister les campagnes d'une boîte","description":"Campagnes qui utilisent la boîte, directement (`email_list`) ou par l'un de ses tags (`email_tag_list`), des plus récentes aux plus anciennes. Liste complète, sans pagination.\n\n**Scope** : `accounts:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"accounts:read","x-min-role":"viewer","parameters":[{"name":"email","in":"path","required":true,"description":"Adresse de la boîte d'envoi (encodée dans l'URL).","schema":{"type":"string","format":"email"},"example":"jeanne@exemple.fr"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"campaign_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"campaign_name":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Statut de la campagne : 0 brouillon, 1 active, 2 en pause, 3 terminée."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["campaign_id","campaign_name","status","timestamp_created"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/account-campaign-mappings/jeanne%40exemple.fr\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/emails":{"get":{"operationId":"getEmails","tags":["Emails / Inbox"],"summary":"Lister les emails","description":"Inbox unifiée : emails envoyés et reçus de toutes les boîtes, des plus récents aux plus anciens (ordre d'enregistrement). Les filtres se combinent. `campaign_id`, `list_id`, `lead`, `assigned_to`, `ai_agent_id`, `eaccount` et `i_status` acceptent plusieurs valeurs séparées par des virgules.\n\n`latest_of_thread` ne garde, pour chaque fil, que son email le plus récent parmi ceux qui passent les filtres : un fil n'apparaît qu'une fois sur l'ensemble des pages, à la place de cet email. Une page peut exceptionnellement compter moins de `limit` emails (fils très longs) ; continuez tant que `next_starting_after` est présent.\n\n**Scope** : `emails:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"emails:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"search","in":"query","required":false,"description":"Contient, dans l'adresse du lead ou l'objet. `thread:<thread_id>` renvoie tous les emails d'un fil.","schema":{"type":"string"}},{"name":"campaign_id","in":"query","required":false,"description":"Campagne(s), UUID séparés par des virgules.","schema":{"type":"string"}},{"name":"list_id","in":"query","required":false,"description":"Liste(s) de leads, UUID séparés par des virgules.","schema":{"type":"string"}},{"name":"lead","in":"query","required":false,"description":"Email(s) du lead, séparés par des virgules.","schema":{"type":"string"}},{"name":"eaccount","in":"query","required":false,"description":"Boîte(s) d'envoi, séparées par des virgules.","schema":{"type":"string"}},{"name":"i_status","in":"query","required":false,"description":"Statut(s) d'intérêt, séparés par des virgules ; `null` inclut les emails non classés (ex. `1,2,null`).","schema":{"type":"string"}},{"name":"assigned_to","in":"query","required":false,"description":"Membre(s) assigné(s), `user_id` séparés par des virgules.","schema":{"type":"string"}},{"name":"ai_agent_id","in":"query","required":false,"description":"Agent(s) IA auteur(s), UUID séparés par des virgules.","schema":{"type":"string"}},{"name":"email_type","in":"query","required":false,"description":"`received` reçus, `sent` tous les envoyés (campagne et à la main), `manual` envoyés à la main seulement (réponses, transferts), `scheduled` programmés ou brouillons IA.","schema":{"type":"string","enum":["received","sent","manual","scheduled"]}},{"name":"is_unread","in":"query","required":false,"description":"true : non lus seulement ; false : lus seulement.","schema":{"type":"boolean"}},{"name":"marked_as_done","in":"query","required":false,"description":"true : traités seulement ; false : non traités seulement.","schema":{"type":"boolean"}},{"name":"has_reminder","in":"query","required":false,"description":"true : emails avec un rappel.","schema":{"type":"boolean"}},{"name":"hide_auto_replies","in":"query","required":false,"description":"true : exclut les réponses automatiques.","schema":{"type":"boolean"}},{"name":"scheduled_only","in":"query","required":false,"description":"true : emails programmés et brouillons IA seulement.","schema":{"type":"boolean"}},{"name":"mode","in":"query","required":false,"description":"Onglet de l'inbox : prioritaire, autres, ou tout (défaut).","schema":{"type":"string","enum":["emode_focused","emode_others","emode_all"]}},{"name":"min_timestamp_created","in":"query","required":false,"description":"Enregistrés à partir de cette date incluse.","schema":{"type":"string","format":"date-time"}},{"name":"max_timestamp_created","in":"query","required":false,"description":"Enregistrés jusqu'à cette date incluse.","schema":{"type":"string","format":"date-time"}},{"name":"latest_of_thread","in":"query","required":false,"description":"true : un seul email par fil, le plus récent parmi ceux qui passent les filtres.","schema":{"type":"boolean"}},{"name":"preview_only","in":"query","required":false,"description":"true : omet `body` (`content_preview` reste), pour des réponses plus légères.","schema":{"type":"boolean"}},{"name":"sort_order","in":"query","required":false,"description":"`desc` plus récents d'abord (défaut), `asc` plus anciens d'abord.","schema":{"type":"string","enum":["desc","asc"]}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Email"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/emails?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/emails/{id}":{"get":{"operationId":"getEmailsById","tags":["Emails / Inbox"],"summary":"Lire un email","description":"Email complet, avec son contenu `body` (`html` et `text`).\n\n**Scope** : `emails:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"emails:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'email (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/emails/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchEmailsById","tags":["Emails / Inbox"],"summary":"Modifier un email","description":"Change l'état de l'email dans l'inbox : lu ou non lu, rappel, traité, membre assigné. Le contenu ne se modifie pas. Renvoie l'email modifié.\n\n**Scope** : `emails:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"emails:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'email (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"is_unread":{"description":"1 ou true : non lu ; 0 ou false : lu.","anyOf":[{"type":"number","const":0},{"type":"number","const":1},{"type":"boolean"}]},"reminder_ts":{"description":"Date de rappel (ISO 8601), null pour retirer le rappel.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"marked_as_done":{"description":"Email traité (filtre `marked_as_done` de `GET /emails`).","type":"boolean"},"assigned_to":{"description":"Membre du workspace (`user_id`) chargé de l'email, null pour le désassigner.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}}},"example":{"is_unread":false,"marked_as_done":true,"reminder_ts":"2026-10-26T08:00:00Z"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/emails/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"is_unread\": false,\n  \"marked_as_done\": true,\n  \"reminder_ts\": \"2026-10-26T08:00:00Z\"\n}'"}]},"delete":{"operationId":"deleteEmailsById","tags":["Emails / Inbox"],"summary":"Supprimer un email","description":"Supprime définitivement l'email de l'inbox Replexa (rien n'est supprimé sur le serveur de messagerie) et renvoie l'email supprimé. Les évènements d'analytics liés à cet email (envoi, ouverture, clic…) sont supprimés avec lui.\n\n**Scope** : `emails:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"emails:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'email (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/emails/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/emails/{id}/feedback":{"post":{"operationId":"postEmailsByIdFeedback","tags":["Emails / Inbox"],"summary":"Corriger la classification d'une réponse","description":"Corrige le statut d'intérêt attribué par l'IA à une réponse. La correction est conservée comme exemple pour le classifieur du workspace.\n\nSi l'email est rattaché à un lead, le statut du lead change comme avec `POST /leads/update-interest-status`, en manuel (l'IA ne l'écrasera plus) : évènement et webhooks, arrêt de la séquence sur un statut définitif, déclenchement des sous-séquences. Sinon (pas de lead, ou lead supprimé) seul `i_status` de l'email change.\n\n400 si `interest_value` n'est ni un statut standard ni le code d'un label du workspace ; rien n'est alors enregistré (ni exemple pour le classifieur, ni changement de statut). 404 si l'email n'existe pas dans le workspace.\n\n**Scope** : `emails:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"emails:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'email (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Statut d'intérêt correct (valeur intégrée ou `interest_status` d'un label personnalisé), null pour revenir au statut « Lead »."}},"required":["interest_value"]},"example":{"interest_value":2}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/emails/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/feedback\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"interest_value\": 2\n}'"}]}},"/emails/forward":{"post":{"operationId":"postEmailsForward","tags":["Emails / Inbox"],"summary":"Transférer un email","description":"Transfère un email de l'inbox à un ou plusieurs destinataires depuis la boîte `eaccount`. Le message saisi est suivi de l'email d'origine (expéditeur, objet, contenu), sauf avec `include_original_body: false`. Côté destinataire, l'envoi ouvre un nouveau fil.\n\nLa signature de la boîte est ajoutée sous le message saisi si elle n'y est pas déjà. L'email envoyé est enregistré dans le fil d'origine (`ue_type` 3, lu) et renvoyé. Aucun évènement d'analytics ni webhook n'est émis : le destinataire n'est pas le lead.\n\nErreurs : 400 si une adresse de `to_address_email_list`, `cc_address_email_list` ou `bcc_address_email_list` est invalide, 404 si l'email ou la boîte est introuvable, 402 si l'abonnement ne permet plus d'envoyer, 502 si le serveur SMTP refuse l'envoi (le message donne la réponse du serveur ; rien n'est enregistré).\n\n**Scope** : `emails:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"emails:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"eaccount":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Boîte d'envoi du workspace qui envoie le transfert."},"reply_to_uuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'email à transférer."},"to_address_email_list":{"type":"string","minLength":3,"description":"Destinataires, séparés par des virgules."},"subject":{"type":"string","minLength":1},"body":{"description":"Message ajouté avant l'email transféré (`html` prioritaire sur `text`).","type":"object","properties":{"html":{"type":"string"},"text":{"type":"string"}}},"include_original_body":{"description":"Joint l'email d'origine (expéditeur, objet et contenu) sous le message. Défaut : true.","type":"boolean"},"cc_address_email_list":{"description":"Copies, séparées par des virgules.","type":"string"},"bcc_address_email_list":{"description":"Copies cachées, séparées par des virgules.","type":"string"}},"required":["eaccount","reply_to_uuid","to_address_email_list","subject"]},"example":{"eaccount":"jeanne@exemple.fr","reply_to_uuid":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","to_address_email_list":"paul@exemple.fr","subject":"TR: Votre stand au salon","body":{"text":"Paul, peux-tu reprendre ce contact ?"}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/emails/forward\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"eaccount\": \"jeanne@exemple.fr\",\n  \"reply_to_uuid\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"to_address_email_list\": \"paul@exemple.fr\",\n  \"subject\": \"TR: Votre stand au salon\",\n  \"body\": {\n    \"text\": \"Paul, peux-tu reprendre ce contact ?\"\n  }\n}'"}]}},"/emails/reply":{"post":{"operationId":"postEmailsReply","tags":["Emails / Inbox"],"summary":"Répondre à un email","description":"Répond dans le fil de l'email `reply_to_uuid` depuis la boîte `eaccount`, avec les en-têtes `In-Reply-To` et `References` pour que la réponse s'affiche dans la conversation du destinataire.\n\n- Destinataires : l'expéditeur de l'email d'origine s'il a été reçu, sinon ses destinataires, plus `additional_recipients`.\n- Objet par défaut : `Re: <objet d'origine>`. La signature de la boîte est ajoutée si elle n'est pas déjà dans le corps. `body.html` ou `body.text` est requis.\n- Effets : les emails reçus du fil passent en lu ; si l'email est rattaché à un lead, sa date de dernier contact est mise à jour et un évènement `sent` est enregistré (webhook `email_sent`).\n\nRenvoie l'email envoyé (`ue_type` 3). 404 si l'email d'origine ou la boîte est introuvable, 402 si l'abonnement ne permet plus d'envoyer, 502 si le serveur SMTP refuse l'envoi (le message donne la réponse du serveur ; rien n'est enregistré). `reyply_to_uuid` est accepté comme alias de `reply_to_uuid`.\n\n**Scope** : `emails:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"emails:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailReply"},"example":{"eaccount":"jeanne@exemple.fr","reply_to_uuid":"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90","body":{"text":"Bonjour Paul,\n\nMerci pour votre retour. Je vous propose un appel jeudi à 10 h.\n\nJeanne"}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/emails/reply\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"eaccount\": \"jeanne@exemple.fr\",\n  \"reply_to_uuid\": \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\",\n  \"body\": {\n    \"text\": \"Bonjour Paul,\\n\\nMerci pour votre retour. Je vous propose un appel jeudi à 10 h.\\n\\nJeanne\"\n  }\n}'"}]}},"/emails/threads/{thread_id}/mark-as-read":{"post":{"operationId":"postEmailsThreadsByThreadIdMarkAsRead","tags":["Emails / Inbox"],"summary":"Marquer un fil comme lu","description":"Passe tous les emails du fil en lu (`is_unread: 0`). Idempotent : un fil inconnu ne renvoie pas d'erreur.\n\n**Scope** : `emails:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"emails:update","x-min-role":"member","parameters":[{"name":"thread_id","in":"path","required":true,"description":"Identifiant du fil (`thread_id` d'un email) (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/emails/threads/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/mark-as-read\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/emails/unread/count":{"get":{"operationId":"getEmailsUnreadCount","tags":["Emails / Inbox"],"summary":"Compter les emails non lus","description":"Nombre d'emails reçus (`ue_type` 2) non lus dans tout le workspace.\n\n**Scope** : `emails:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"emails:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["count"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/emails/unread/count\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-agents":{"get":{"operationId":"getAiAgents","tags":["Agents IA"],"summary":"Lister les agents","description":"Agents de réponse du workspace, des plus récents aux plus anciens. Les consignes et les statistiques ne sont renvoyées que par `GET /ai-agents/{id}`.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AiAgent"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-agents?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postAiAgents","tags":["Agents IA"],"summary":"Créer un agent","description":"Crée un agent de réponse. Seul `name` est obligatoire ; les champs absents prennent leur valeur par défaut (mode `human_in_loop` : chaque brouillon attend une validation).\n\nUne campagne n'a qu'un agent : les campagnes de `campaign_ids` sont rattachées à ce nouvel agent et retirées des autres agents du workspace. Un identifiant de `campaign_ids`, `tool_ids` ou `skill_ids` inconnu ou d'un autre workspace renvoie 400. Renvoie l'agent créé.\n\n**Scope** : `ai_agents:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentCreate"},"example":{"name":"Agent salons","mode":"human_in_loop","campaign_ids":["0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90"],"instructions":"Tu réponds au nom de Jeanne, responsable commerciale. Tu restes bref et tu vouvoies.","knowledge":"Stands modulaires de 9 à 36 m², livrés et montés. Devis sous 48 h.","objective":"book_meeting","booking_url":"https://cal.exemple.fr/jeanne","tone":"friendly"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgent"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-agents\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Agent salons\",\n  \"mode\": \"human_in_loop\",\n  \"campaign_ids\": [\n    \"0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\"\n  ],\n  \"instructions\": \"Tu réponds au nom de Jeanne, responsable commerciale. Tu restes bref et tu vouvoies.\",\n  \"knowledge\": \"Stands modulaires de 9 à 36 m², livrés et montés. Devis sous 48 h.\",\n  \"objective\": \"book_meeting\",\n  \"booking_url\": \"https://cal.exemple.fr/jeanne\",\n  \"tone\": \"friendly\"\n}'"}]}},"/ai-agents/{id}":{"get":{"operationId":"getAiAgentsById","tags":["Agents IA"],"summary":"Lire un agent","description":"Réglages de l'agent, avec ses consignes (`guidance`) et ses chiffres clés (`stats`) : réponses traitées, brouillons en attente, envois, polarité des réponses et objectifs atteints.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentDetail"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchAiAgentsById","tags":["Agents IA"],"summary":"Modifier un agent","description":"Modifie les champs envoyés ; les autres restent inchangés. Les objets (`on_positive`, `no_show`, `working_hours`...) et les listes sont remplacés en entier.\n\n`campaign_ids` est la liste complète des campagnes de l'agent : les campagnes absentes sont détachées, celles ajoutées sont retirées de leur agent précédent. Un identifiant de `campaign_ids`, `tool_ids` ou `skill_ids` inconnu ou d'un autre workspace renvoie 400. Renvoie l'agent modifié, sans consignes ni statistiques.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentPatch"},"example":{"mode":"autopilot","reply_delay_minutes":30,"on_negative":{"action":"review","instructions":"Remercie et demande qui contacter."}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgent"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"mode\": \"autopilot\",\n  \"reply_delay_minutes\": 30,\n  \"on_negative\": {\n    \"action\": \"review\",\n    \"instructions\": \"Remercie et demande qui contacter.\"\n  }\n}'"}]},"delete":{"operationId":"deleteAiAgentsById","tags":["Agents IA"],"summary":"Supprimer un agent","description":"Supprime l'agent avec ses consignes et son journal d'activité. Ses campagnes n'ont plus d'agent et les emails qu'il a envoyés restent dans l'inbox. Ses brouillons non envoyés (à valider, ou programmés en autopilot) sont rejetés comme par `POST /ai-agents/activity/{id}/reject` : ils passent en `rejected`, l'envoi programmé est annulé et ils restent visibles dans l'inbox. Un brouillon déjà en cours d'envoi n'est pas touché. Renvoie l'agent supprimé.\n\n**Scope** : `ai_agents:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgent"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-agents/{id}/guidance":{"get":{"operationId":"getAiAgentsByIdGuidance","tags":["Agents IA"],"summary":"Lister les consignes d'un agent","description":"Toutes les consignes de l'agent, désactivées comprises, triées par catégorie puis par position. Liste complète, sans pagination.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AiAgentGuidance"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/guidance\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postAiAgentsByIdGuidance","tags":["Agents IA"],"summary":"Ajouter une consigne","description":"Ajoute une consigne à l'agent. Les consignes actives (`status` 1) sont transmises à l'agent à chaque rédaction, regroupées par catégorie. Renvoie la consigne créée.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"category":{"default":4,"description":"0 bases, 1 style de communication, 2 précisions de contexte, 3 passage de relais et escalade, 4 autre (défaut).","type":"integer","minimum":0,"maximum":4},"label":{"type":"string","minLength":1,"description":"Titre court de la consigne."},"instruction":{"type":"string","minLength":1,"description":"Texte de la consigne, transmis tel quel à l'agent."},"status":{"description":"1 active (défaut), 0 désactivée (ignorée par l'agent).","type":"integer","minimum":0,"maximum":1},"position":{"description":"Ordre d'affichage dans la catégorie (défaut 0).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["label","instruction"]},"example":{"category":1,"label":"Vouvoiement","instruction":"Vouvoie toujours le prospect, même s'il tutoie."}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentGuidance"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/guidance\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"category\": 1,\n  \"label\": \"Vouvoiement\",\n  \"instruction\": \"Vouvoie toujours le prospect, même s'\\''il tutoie.\"\n}'"}]}},"/ai-agents/{id}/guidance/{guidance_id}":{"patch":{"operationId":"patchAiAgentsByIdGuidanceByGuidanceId","tags":["Agents IA"],"summary":"Modifier une consigne","description":"Modifie les champs envoyés de la consigne. Passez `status` à 0 pour la désactiver sans la supprimer. Renvoie la consigne modifiée.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}},{"name":"guidance_id","in":"path","required":true,"description":"Identifiant de la consigne (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"category":{"description":"0 bases, 1 style de communication, 2 précisions de contexte, 3 passage de relais et escalade, 4 autre.","type":"integer","minimum":0,"maximum":4},"label":{"description":"Titre court de la consigne.","type":"string","minLength":1},"instruction":{"description":"Texte de la consigne.","type":"string","minLength":1},"status":{"description":"1 active, 0 désactivée.","type":"integer","minimum":0,"maximum":1},"position":{"description":"Ordre d'affichage dans la catégorie.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}}},"example":{"status":0}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentGuidance"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/guidance/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"status\": 0\n}'"}]},"delete":{"operationId":"deleteAiAgentsByIdGuidanceByGuidanceId","tags":["Agents IA"],"summary":"Supprimer une consigne","description":"Supprime définitivement la consigne. Renvoie la consigne supprimée.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}},{"name":"guidance_id","in":"path","required":true,"description":"Identifiant de la consigne (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentGuidance"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/guidance/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-agents/{id}/simulate":{"post":{"operationId":"postAiAgentsByIdSimulate","tags":["Agents IA"],"summary":"Simuler une réponse","description":"Bac à sable : classe la réponse fournie (`reply`) puis rédige le brouillon que l'agent produirait, sans rien envoyer ni écrire (aucun email, aucune entrée de journal, aucun lead modifié). Seule la consommation IA est comptabilisée.\n\n`agent` applique des réglages non enregistrés à cette simulation uniquement ; les consignes actives enregistrées s'appliquent toujours. Les outils de lecture autorisés (créneaux libres, recherche CRM, outils HTTP ou MCP sans `side_effect`) sont réellement appelés pour un brouillon réaliste ; les actions sont seulement listées dans `deferred_actions`.\n\nRenvoie la classification, la règle appliquée, le brouillon et `outcome` : ce que l'agent ferait vraiment (`no_reply`, `review` ou `autopilot`) avec la raison. Erreurs : 402 si les crédits IA du mois sont épuisés (ou l'abonnement suspendu), 422 si le modèle refuse la demande, 502 si l'API d'IA échoue ou rend une réponse inexploitable, 503 si l'IA n'est pas configurée sur l'instance (`ANTHROPIC_API_KEY` absente).\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"ai_agents:update","x-min-role":"member","x-rate-limit":"20/min","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'agent (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reply":{"type":"string","minLength":1,"maxLength":8000},"subject":{"default":"Re: notre échange","type":"string","maxLength":300},"previous":{"type":"string","maxLength":8000},"lead":{"default":{},"type":"object","properties":{"email":{"default":"prospect@exemple.com","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"default":null,"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"last_name":{"default":null,"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"company_name":{"default":null,"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"job_title":{"default":null,"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]}}},"agent":{"type":"object","properties":{"name":{"type":"string","minLength":1},"mode":{"type":"string","enum":["off","human_in_loop","autopilot"]},"status":{"type":"integer","minimum":0,"maximum":1},"instructions":{"type":"string"},"knowledge":{"type":"string"},"booking_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"signature":{"type":["string","null"]},"language":{"type":"string"},"reply_delay_minutes":{"type":"integer","minimum":0,"maximum":9007199254740991},"escalate_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"campaign_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"account_emails":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"handle_followup":{"type":"boolean"},"followup_after_days":{"type":"integer","minimum":1,"maximum":9007199254740991},"max_followups":{"type":"integer","minimum":0,"maximum":10},"followup_business_days_only":{"type":"boolean"},"respond_to_automatic_emails":{"type":"boolean"},"handle_objections":{"type":"boolean"},"trigger_on_labels_enabled":{"type":"boolean"},"trigger_on_labels_mode":{"type":"string","enum":["include","exclude"]},"trigger_on_labels":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"monthly_credit_budget":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"no_show":{"type":"object","properties":{"enabled":{"type":"boolean"},"max_followups":{"type":"integer","minimum":0,"maximum":10}},"required":["enabled","max_followups"]},"tone":{"type":"string","enum":["friendly","neutral","matter_of_fact","professional","humorous"]},"length":{"type":"string","enum":["concise","standard","thorough"]},"working_hours":{"anyOf":[{},{"type":"null"}]},"objective":{"type":"string","enum":["book_meeting","call_back","send_info","qualify","custom"]},"objective_details":{"type":"string"},"on_positive":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"]},"on_negative":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"]},"on_neutral":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"]},"tool_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"skill_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"code_execution":{"type":"boolean"},"integration_providers":{"type":"array","items":{"type":"string","enum":["google_calendar","airtable","hubspot","pipedrive","salesforce"]}}}}},"required":["reply"]},"example":{"reply":"Bonjour, votre offre m'intéresse. Vous auriez un créneau jeudi pour en parler ?","subject":"Re: votre stand au salon","lead":{"email":"paul@exemple.fr","first_name":"Paul","company_name":"Atelier Martin"},"agent":{"mode":"autopilot","tone":"friendly"}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentSimulation"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-agents/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/simulate\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"reply\": \"Bonjour, votre offre m'\\''intéresse. Vous auriez un créneau jeudi pour en parler ?\",\n  \"subject\": \"Re: votre stand au salon\",\n  \"lead\": {\n    \"email\": \"paul@exemple.fr\",\n    \"first_name\": \"Paul\",\n    \"company_name\": \"Atelier Martin\"\n  },\n  \"agent\": {\n    \"mode\": \"autopilot\",\n    \"tone\": \"friendly\"\n  }\n}'"}]}},"/ai-agents/activity":{"get":{"operationId":"getAiAgentsActivity","tags":["Agents IA"],"summary":"Lister l'activité des agents","description":"Journal des agents du workspace, du plus récent au plus ancien : réponses traitées, brouillons, relances, erreurs (budget ou crédits épuisés, échec d'envoi). Chaque entrée inclut le brouillon (`draft`) et la réponse du prospect (`source`).\n\nAvec `action_pending=true`, renvoie la file de validation : les brouillons à approuver (`POST /ai-agents/activity/{id}/approve`) ou à rejeter.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"agent_id","in":"query","required":false,"description":"Uniquement l'activité de cet agent.","schema":{"type":"string","format":"uuid"}},{"name":"action_pending","in":"query","required":false,"description":"`true` (ou `1`) : seulement les brouillons en attente de validation ; toute autre valeur : seulement les entrées traitées. Absent : tout le journal.","schema":{"type":"boolean"},"example":true}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AiAgentActivity"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-agents/activity?limit=10&action_pending=true\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-agents/activity/{id}/approve":{"post":{"operationId":"postAiAgentsActivityByIdApprove","tags":["Agents IA"],"summary":"Valider et envoyer un brouillon","description":"Envoie tout de suite le brouillon de l'entrée, dans le fil de la réponse du prospect, depuis la boîte prévue (avec la signature de la boîte). Un `body` remplace le texte rédigé par l'agent. Les messages reçus du fil passent en lus et l'envoi est enregistré sur le lead (webhook `email_sent`).\n\nEnsuite, si `run_actions` vaut true (défaut), les actions mises en attente par l'agent sont exécutées (rendez-vous, écriture CRM, appel d'API) ; leur résultat est dans `actions`. L'entrée sort de la file de validation.\n\nErreurs : 400 si l'entrée n'a pas de brouillon, 409 si le brouillon est déjà envoyé, en cours d'envoi ou rejeté (le message précise le cas), 402 si l'envoi est suspendu par la facturation. Si le serveur SMTP refuse l'envoi (erreur 502, avec sa réponse), le brouillon reprend son état précédent.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'entrée du journal (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"description":"Version modifiée du brouillon. `html` prime ; avec `text` seul, le HTML est généré depuis le texte. Absent : le brouillon est envoyé tel quel.","type":"object","properties":{"text":{"type":"string"},"html":{"type":"string"}}},"run_actions":{"default":true,"description":"Exécuter les actions mises en attente par l'agent (rendez-vous, écriture CRM, appel d'API). Défaut true.","type":"boolean"}}},"example":{"body":{"text":"Bonjour Paul,\n\nJeudi à 10 h me convient très bien, je vous envoie l'invitation.\n\nJeanne"},"run_actions":true}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentSentReply"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"402":{"$ref":"#/components/responses/E402"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-agents/activity/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/approve\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"body\": {\n    \"text\": \"Bonjour Paul,\\n\\nJeudi à 10 h me convient très bien, je vous envoie l'\\''invitation.\\n\\nJeanne\"\n  },\n  \"run_actions\": true\n}'"}]}},"/ai-agents/activity/{id}/reject":{"post":{"operationId":"postAiAgentsActivityByIdReject","tags":["Agents IA"],"summary":"Rejeter un brouillon","description":"Rejette le brouillon de l'entrée : il n'est pas envoyé (un envoi automatique programmé est annulé), passe en `rejected` et reste visible dans l'inbox. Les actions en attente sont abandonnées et l'entrée sort de la file de validation. Erreur 400 si l'entrée n'a pas de brouillon, 409 s'il est déjà envoyé ou en cours d'envoi.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'entrée du journal (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-agents/activity/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/reject\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-tools":{"get":{"operationId":"getAiTools","tags":["Outils et skills"],"summary":"Lister les outils","description":"Outils HTTP et serveurs MCP du workspace, triés par nom affiché. Un outil n'est utilisé que par les agents qui l'autorisent dans `tool_ids`. Liste complète, sans pagination.\n\nLe jeton (`secret`) n'est jamais renvoyé : seul `has_secret` indique sa présence. Les valeurs de `config.headers` ne sont lisibles qu'avec le rôle admin ou owner ; pour un viewer ou un member, chaque valeur est remplacée par `••••••`.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AiTool"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-tools\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postAiTools","tags":["Outils et skills"],"summary":"Créer un outil","description":"Enregistre une API HTTP ou un serveur MCP que les agents pourront appeler. `secret` est chiffré et ne sera plus jamais renvoyé. Pour un serveur MCP, appelez ensuite `POST /ai-tools/{id}/discover` puis activez les outils voulus dans `mcp_tools`. Erreur 409 si un outil porte déjà ce `name`. Renvoie l'outil créé.\n\nLe jeton (`secret`) n'est jamais renvoyé : seul `has_secret` indique sa présence. Les valeurs de `config.headers` ne sont lisibles qu'avec le rôle admin ou owner ; pour un viewer ou un member, chaque valeur est remplacée par `••••••`.\n\n**Scope** : `ai_agents:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiToolCreate"},"example":{"name":"verifier_stock","label":"Vérifier le stock","description":"Renvoie le stock disponible d'une référence produit. À utiliser quand le prospect demande un délai de livraison.","kind":"http","config":{"method":"GET","url":"https://api.exemple.fr/stock/{{reference}}"},"auth":{"type":"bearer"},"secret":"jeton-api-exemple","input_schema":{"type":"object","properties":{"reference":{"type":"string","description":"Référence produit"}},"required":["reference"]}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiTool"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-tools\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"verifier_stock\",\n  \"label\": \"Vérifier le stock\",\n  \"description\": \"Renvoie le stock disponible d'\\''une référence produit. À utiliser quand le prospect demande un délai de livraison.\",\n  \"kind\": \"http\",\n  \"config\": {\n    \"method\": \"GET\",\n    \"url\": \"https://api.exemple.fr/stock/{{reference}}\"\n  },\n  \"auth\": {\n    \"type\": \"bearer\"\n  },\n  \"secret\": \"jeton-api-exemple\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"reference\": {\n        \"type\": \"string\",\n        \"description\": \"Référence produit\"\n      }\n    },\n    \"required\": [\n      \"reference\"\n    ]\n  }\n}'"}]}},"/ai-tools/{id}":{"get":{"operationId":"getAiToolsById","tags":["Outils et skills"],"summary":"Lire un outil","description":"Réglages de l'outil.\n\nLe jeton (`secret`) n'est jamais renvoyé : seul `has_secret` indique sa présence. Les valeurs de `config.headers` ne sont lisibles qu'avec le rôle admin ou owner ; pour un viewer ou un member, chaque valeur est remplacée par `••••••`.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'outil (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiTool"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-tools/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchAiToolsById","tags":["Outils et skills"],"summary":"Modifier un outil","description":"Modifie les champs envoyés. `config` est fusionnée avec la configuration enregistrée : seuls ses champs envoyés changent (`url`, `method`, `body_template` absents gardent leur valeur ; `body_template: null` l'efface). `auth` est remplacé en entier. `config.headers`, s'il est envoyé, remplace la liste des en-têtes ; sans lui, les en-têtes enregistrés sont gardés si l'adresse reste sur la même origine, supprimés sinon. Une valeur d'en-tête `••••••` (telle que lue par un non-admin) conserve la valeur enregistrée.\n\nUn secret n'est jamais envoyé vers une nouvelle adresse sans être ressaisi : changer l'origine de `config.url` ou `auth.header_name` alors qu'un jeton est enregistré exige `secret` (sinon 400), et un en-tête `••••••` vers une autre origine est refusé (400). `auth.type` `none` efface le jeton. Renvoie l'outil modifié.\n\nLe jeton (`secret`) n'est jamais renvoyé : seul `has_secret` indique sa présence. Les valeurs de `config.headers` ne sont lisibles qu'avec le rôle admin ou owner ; pour un viewer ou un member, chaque valeur est remplacée par `••••••`.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'outil (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiToolPatch"},"example":{"label":"Stock en temps réel","enabled":false}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiTool"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/ai-tools/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"label\": \"Stock en temps réel\",\n  \"enabled\": false\n}'"}]},"delete":{"operationId":"deleteAiToolsById","tags":["Outils et skills"],"summary":"Supprimer un outil","description":"Retire l'outil des agents qui l'autorisaient (`tool_ids`), puis le supprime avec son jeton. Renvoie l'outil supprimé (sans le jeton).\n\n**Scope** : `ai_agents:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'outil (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiTool"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/ai-tools/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-tools/{id}/discover":{"post":{"operationId":"postAiToolsByIdDiscover","tags":["Outils et skills"],"summary":"Découvrir les outils d'un serveur MCP","description":"Se connecte au serveur MCP (avec le jeton enregistré) et met à jour `mcp_tools` avec la liste de ses outils. Les choix existants (`enabled`, `side_effect`) sont conservés ; un nouvel outil est désactivé et marqué comme action si son nom évoque une écriture (`create`, `update`, `delete`, `send`...). Les outils disparus du serveur sont retirés.\n\nErreur 400 si l'outil n'est pas de type `mcp` ou si sa configuration est refusée (URL invalide ou non publique) ; 502 si la connexion au serveur MCP ou la liste de ses outils échoue (le message donne la cause). Renvoie l'outil mis à jour.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"ai_agents:update","x-min-role":"member","x-rate-limit":"20/min","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'outil (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiTool"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-tools/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/discover\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/ai-tools/{id}/test":{"post":{"operationId":"postAiToolsByIdTest","tags":["Outils et skills"],"summary":"Tester un outil","description":"Appelle l'outil immédiatement avec `input`, hors de tout agent. Attention : un outil d'action (`side_effect`) est réellement exécuté. Pour un serveur MCP, `mcp_tool` est obligatoire et doit désigner un outil activé dans `mcp_tools` (`enabled: true`), sinon 400 : lancez `POST /ai-tools/{id}/discover` puis activez-le. Pour un outil `http`, `mcp_tool` est ignoré. L'appel expire après 20 secondes et la sortie est tronquée à 6 000 caractères.\n\nUne fois la requête validée, la réponse est toujours 200, même si l'outil échoue : `success` vaut false, avec le message d'erreur dans `output`, si l'appel échoue (connexion, délai dépassé), si le service répond par une erreur HTTP, si l'outil MCP renvoie une erreur ou si l'outil est désactivé (`enabled: false`). Testez donc `success`, pas le code HTTP.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"ai_agents:update","x-min-role":"member","x-rate-limit":"20/min","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'outil (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"default":{},"description":"Paramètres passés à l'outil (défaut `{}`).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"mcp_tool":{"description":"Nom de l'outil du serveur à appeler : obligatoire pour un outil `mcp`, et activé dans ses `mcp_tools`. Ignoré pour un outil `http`.","type":"string"}}},"example":{"input":{"reference":"REF-1042"}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"L'appel a abouti."},"output":{"type":"string","description":"Réponse de l'outil, ou message d'erreur."},"duration_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Durée de l'appel en millisecondes."}},"required":["success","output","duration_ms"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-tools/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/test\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"input\": {\n    \"reference\": \"REF-1042\"\n  }\n}'"}]}},"/ai-skills":{"get":{"operationId":"getAiSkills","tags":["Outils et skills"],"summary":"Lister les skills","description":"Skills du workspace, triées par nom : des instructions réutilisables qu'un agent charge à la demande quand elles sont autorisées dans ses `skill_ids`. Liste complète, sans pagination.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AiSkill"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-skills\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postAiSkills","tags":["Outils et skills"],"summary":"Créer une skill","description":"Crée une skill. L'agent ne voit que `name` et `description` et charge `content` quand il juge la skill utile. Erreur 409 si une skill porte déjà ce `name`. Renvoie la skill créée.\n\n**Scope** : `ai_agents:create` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:create","x-min-role":"member","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSkillCreate"},"example":{"name":"demande-devis","description":"À utiliser quand le prospect demande un devis ou un tarif.","content":"## Demande de devis\n\n1. Demander la surface du stand et la date du salon.\n2. Annoncer un devis sous 48 h.\n3. Proposer un appel de 15 minutes."}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSkill"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/ai-skills\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"demande-devis\",\n  \"description\": \"À utiliser quand le prospect demande un devis ou un tarif.\",\n  \"content\": \"## Demande de devis\\n\\n1. Demander la surface du stand et la date du salon.\\n2. Annoncer un devis sous 48 h.\\n3. Proposer un appel de 15 minutes.\"\n}'"}]}},"/ai-skills/{id}":{"get":{"operationId":"getAiSkillsById","tags":["Outils et skills"],"summary":"Lire une skill","description":"La skill avec son contenu complet.\n\n**Scope** : `ai_agents:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:read","x-min-role":"viewer","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la skill (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSkill"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/ai-skills/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchAiSkillsById","tags":["Outils et skills"],"summary":"Modifier une skill","description":"Modifie les champs envoyés. Les agents qui l'autorisent utilisent la nouvelle version dès leur prochaine rédaction. Erreur 409 si le nouveau `name` est déjà pris. Renvoie la skill modifiée.\n\n**Scope** : `ai_agents:update` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:update","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la skill (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSkillPatch"},"example":{"description":"À utiliser dès que le prospect parle de prix, de budget ou de devis."}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSkill"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/ai-skills/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"description\": \"À utiliser dès que le prospect parle de prix, de budget ou de devis.\"\n}'"}]},"delete":{"operationId":"deleteAiSkillsById","tags":["Outils et skills"],"summary":"Supprimer une skill","description":"Retire la skill des agents qui l'autorisaient (`skill_ids`), puis la supprime. Renvoie la skill supprimée.\n\n**Scope** : `ai_agents:delete` · **Rôle minimum** : membre (member) · **Limite** : 600 requêtes par minute","x-scope":"ai_agents:delete","x-min-role":"member","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la skill (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSkill"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/ai-skills/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations":{"get":{"operationId":"getIntegrations","tags":["Intégrations"],"summary":"Lire l'état des intégrations","description":"État de toutes les intégrations natives du workspace en un appel : `google_calendar`, `airtable`, `hubspot`, `pipedrive` et `salesforce`. Une intégration jamais connectée apparaît avec `status: \"disconnected\"`. Aucun secret n'est renvoyé (jetons, clés et secrets OAuth restent chiffrés en base).\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"google_calendar":{"type":"object","properties":{"configured":{"type":"boolean","description":"Une application Google (ID client et secret) est disponible, celle du workspace ou celle de l'instance."},"connected":{"type":"boolean","description":"L'intégration est utilisable (statut `connected` et jeton présent)."},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"account_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}],"description":"Compte connecté côté service."},"last_error":{"type":["string","null"]},"public_config":{"type":"object","properties":{"client_id":{"type":"string"}},"additionalProperties":false,"description":"ID client enregistré. Le secret et les jetons OAuth ne sont jamais renvoyés."},"settings":{"anyOf":[{"type":"object","properties":{"calendar_id":{"type":"string","minLength":1,"description":"Agenda où les rendez-vous sont créés (`primary` ou un identifiant de `GET /integrations/google-calendar/calendars`)."},"timezone":{"type":"string","description":"Fuseau IANA des horaires (ex. `Europe/Luxembourg`)."},"days":{"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6},"description":"Jours proposés, 0 = dimanche … 6 = samedi."},"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Début de la plage horaire (HH:MM)."},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Fin de la plage horaire (HH:MM), après `from`."},"duration_minutes":{"type":"integer","minimum":10,"maximum":240,"description":"Durée d'un rendez-vous."},"buffer_minutes":{"type":"integer","minimum":0,"maximum":120,"description":"Marge laissée libre avant et après chaque évènement existant."},"min_notice_hours":{"type":"number","minimum":0,"maximum":336,"description":"Délai minimum avant le premier créneau proposé."},"max_days_ahead":{"type":"integer","minimum":1,"maximum":60,"description":"Horizon maximum des créneaux proposés, en jours."},"add_meet":{"type":"boolean","description":"Ajouter un lien Google Meet au rendez-vous."},"title_template":{"type":"string","maxLength":200,"description":"Titre du rendez-vous, variables du lead acceptées (`{{companyName}}`…)."},"description_template":{"type":"string","maxLength":2000,"description":"Description du rendez-vous, variables du lead acceptées."},"check_calendars":{"type":"array","items":{"type":"string"},"description":"Agendas supplémentaires dont les évènements bloquent aussi des créneaux."}},"required":["calendar_id","timezone","days","from","to","duration_minutes","buffer_minutes","min_notice_hours","max_days_ahead","add_meet","title_template","description_template","check_calendars"],"additionalProperties":false},{"type":"null"}],"description":"Réglages de prise de rendez-vous, `null` si rien n'est enregistré."}},"required":["configured","connected","status","account_email","last_error","public_config","settings"],"additionalProperties":false},"airtable":{"type":"object","properties":{"configured":{"type":"boolean","description":"Des identifiants sont enregistrés."},"connected":{"type":"boolean","description":"L'intégration est utilisable (statut `connected` et jeton présent)."},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"account_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}],"description":"Compte connecté côté service."},"last_error":{"type":["string","null"]},"public_config":{"type":"object","properties":{"user_id":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"token_hint":{"type":"string","description":"4 derniers caractères du jeton, précédés de `…`."}},"additionalProperties":false,"description":"Partie non secrète de la configuration. Le jeton lui-même n'est jamais renvoyé."},"settings":{"anyOf":[{"type":"object","properties":{"base_ids":{"type":"array","items":{"type":"string","pattern":"^app[A-Za-z0-9]+$"},"description":"Identifiants des bases autorisées (`app…`). Liste vide : aucune base."}},"required":["base_ids"],"additionalProperties":false},{"type":"null"}],"description":"Bases autorisées pour les agents IA, `null` si Airtable n'a jamais été connecté."}},"required":["configured","connected","status","account_email","last_error","public_config","settings"],"additionalProperties":false},"hubspot":{"type":"object","properties":{"provider":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"connected":{"type":"boolean"},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"mode":{"anyOf":[{"type":"string","enum":["oauth","token"]},{"type":"null"}],"description":"Mode de connexion, `null` si non connecté."},"account_email":{"type":["string","null"]},"account_name":{"description":"Nom du compte ou du portail côté CRM.","type":["string","null"]},"token_hint":{"description":"4 derniers caractères du jeton (mode `token`). Le jeton et les jetons OAuth ne sont jamais renvoyés.","type":["string","null"]},"last_error":{"type":["string","null"]},"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}},"required":["sync_enabled","sync_on","create_deal_on_positive","deal_stage","status_map"],"additionalProperties":false,"description":"Réglages de synchronisation (valeurs par défaut du CRM si non connecté)."},"oauth_available":{"type":"boolean","description":"L'application OAuth Replexa de ce CRM est configurée sur l'instance."},"token_available":{"type":"boolean","description":"Connexion par jeton possible (HubSpot, Pipedrive ; jamais Salesforce)."}},"required":["provider","connected","status","mode","account_email","account_name","token_hint","last_error","settings","oauth_available","token_available"],"additionalProperties":false},"pipedrive":{"type":"object","properties":{"provider":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"connected":{"type":"boolean"},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"mode":{"anyOf":[{"type":"string","enum":["oauth","token"]},{"type":"null"}],"description":"Mode de connexion, `null` si non connecté."},"account_email":{"type":["string","null"]},"account_name":{"description":"Nom du compte ou du portail côté CRM.","type":["string","null"]},"token_hint":{"description":"4 derniers caractères du jeton (mode `token`). Le jeton et les jetons OAuth ne sont jamais renvoyés.","type":["string","null"]},"last_error":{"type":["string","null"]},"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}},"required":["sync_enabled","sync_on","create_deal_on_positive","deal_stage","status_map"],"additionalProperties":false,"description":"Réglages de synchronisation (valeurs par défaut du CRM si non connecté)."},"oauth_available":{"type":"boolean","description":"L'application OAuth Replexa de ce CRM est configurée sur l'instance."},"token_available":{"type":"boolean","description":"Connexion par jeton possible (HubSpot, Pipedrive ; jamais Salesforce)."}},"required":["provider","connected","status","mode","account_email","account_name","token_hint","last_error","settings","oauth_available","token_available"],"additionalProperties":false},"salesforce":{"type":"object","properties":{"provider":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"connected":{"type":"boolean"},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"mode":{"anyOf":[{"type":"string","enum":["oauth","token"]},{"type":"null"}],"description":"Mode de connexion, `null` si non connecté."},"account_email":{"type":["string","null"]},"account_name":{"description":"Nom du compte ou du portail côté CRM.","type":["string","null"]},"token_hint":{"description":"4 derniers caractères du jeton (mode `token`). Le jeton et les jetons OAuth ne sont jamais renvoyés.","type":["string","null"]},"last_error":{"type":["string","null"]},"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}},"required":["sync_enabled","sync_on","create_deal_on_positive","deal_stage","status_map"],"additionalProperties":false,"description":"Réglages de synchronisation (valeurs par défaut du CRM si non connecté)."},"oauth_available":{"type":"boolean","description":"L'application OAuth Replexa de ce CRM est configurée sur l'instance."},"token_available":{"type":"boolean","description":"Connexion par jeton possible (HubSpot, Pipedrive ; jamais Salesforce)."}},"required":["provider","connected","status","mode","account_email","account_name","token_hint","last_error","settings","oauth_available","token_available"],"additionalProperties":false}},"required":["google_calendar","airtable","hubspot","pipedrive","salesforce"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/airtable":{"get":{"operationId":"getIntegrationsAirtable","tags":["Intégrations"],"summary":"Lire l'intégration Airtable","description":"État de la connexion Airtable et bases autorisées pour les agents IA (`settings.base_ids`). Le jeton n'est jamais renvoyé, seuls ses 4 derniers caractères (`public_config.token_hint`).\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirtableIntegration"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/airtable\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postIntegrationsAirtable","tags":["Intégrations"],"summary":"Connecter Airtable","description":"Vérifie le jeton d'accès personnel auprès d'Airtable (compte et bases accessibles), puis l'enregistre chiffré en remplaçant le jeton précédent. À la première connexion, aucune base n'est autorisée : choisissez-les ensuite avec `PATCH /integrations/airtable`. Lors d'un remplacement, les bases déjà autorisées et encore visibles par le nouveau jeton sont conservées. Renvoie le compte et toutes les bases accessibles. Un jeton refusé par Airtable (401 ou 403) répond 400 avec le message d'Airtable ; une panne ou une autre erreur d'Airtable répond 502. Dans les deux cas, rien n'est modifié.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirtableConnect"},"example":{"api_key":"patExempleJetonAirtable.0000000000000000"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"account_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"bases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la base (`app…`)."},"name":{"type":"string"},"permissionLevel":{"type":"string","description":"Droits du jeton sur la base (`read`, `edit`, `create`…)."}},"required":["id","name","permissionLevel"],"additionalProperties":false}}},"required":["success","account_email","bases"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/integrations/airtable\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"api_key\": \"patExempleJetonAirtable.0000000000000000\"\n}'"}]},"patch":{"operationId":"patchIntegrationsAirtable","tags":["Intégrations"],"summary":"Choisir les bases Airtable autorisées","description":"Remplace la liste des bases que les agents IA peuvent lire et modifier. Les identifiants inconnus du jeton sont retirés sans erreur (sauf si la liste des bases ne peut pas être lue chez Airtable : tout est alors gardé). Renvoie la liste retenue. Répond 400 si Airtable n'a jamais été connecté.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirtableSettingsPatch"},"example":{"settings":{"base_ids":["appX1y2Z3a4B5c6D7"]}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"settings":{"type":"object","properties":{"base_ids":{"type":"array","items":{"type":"string","pattern":"^app[A-Za-z0-9]+$"},"description":"Identifiants des bases autorisées (`app…`). Liste vide : aucune base."}},"required":["base_ids"],"additionalProperties":false}},"required":["settings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/integrations/airtable\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"settings\": {\n    \"base_ids\": [\n      \"appX1y2Z3a4B5c6D7\"\n    ]\n  }\n}'"}]},"delete":{"operationId":"deleteIntegrationsAirtable","tags":["Intégrations"],"summary":"Déconnecter Airtable","description":"Supprime le jeton et les réglages Airtable. Les agents IA qui utilisaient Airtable le perdent de leurs intégrations. Sans effet si Airtable n'était pas connecté.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/integrations/airtable\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/airtable/bases":{"get":{"operationId":"getIntegrationsAirtableBases","tags":["Intégrations"],"summary":"Lister les bases Airtable","description":"Toutes les bases accessibles avec le jeton enregistré (jusqu'à 1000 environ), lues en direct chez Airtable. Répond 400 si Airtable n'est pas connecté, 502 si Airtable renvoie une erreur ou ne répond pas.\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AirtableBase"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/airtable/bases\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/airtable/tables":{"get":{"operationId":"getIntegrationsAirtableTables","tags":["Intégrations"],"summary":"Lister les tables d'une base Airtable","description":"Tables d'une base et, pour chacune, le nom et le type de ses champs, lus en direct chez Airtable. La base n'a pas besoin d'être autorisée pour les agents. Répond 400 si `base_id` est absent ou mal formé, si Airtable n'est pas connecté ou si la base est inconnue ou inaccessible avec ce jeton (403 ou 404 d'Airtable) ; 502 pour toute autre erreur d'Airtable.\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","parameters":[{"name":"base_id","in":"query","required":true,"description":"Identifiant de la base (`app…`).","schema":{"type":"string"},"example":"appX1y2Z3a4B5c6D7"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AirtableTable"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/airtable/tables?base_id=appX1y2Z3a4B5c6D7\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/crm/{provider}":{"get":{"operationId":"getIntegrationsCrmByProvider","tags":["Intégrations"],"summary":"Lire l'intégration d'un CRM","description":"État de la connexion au CRM, mode (`oauth` ou `token`), réglages de synchronisation et modes de connexion disponibles. `redirect_uri` est l'adresse de retour OAuth à déclarer dans l'application du CRM. La connexion OAuth elle-même se fait depuis la page Intégrations de l'interface, pas par l'API. Aucun jeton n'est renvoyé.\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","parameters":[{"name":"provider","in":"path","required":true,"description":"CRM concerné. Toute autre valeur répond 404.","schema":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"example":"hubspot"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"connected":{"type":"boolean"},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"mode":{"anyOf":[{"type":"string","enum":["oauth","token"]},{"type":"null"}],"description":"Mode de connexion, `null` si non connecté."},"account_email":{"type":["string","null"]},"account_name":{"description":"Nom du compte ou du portail côté CRM.","type":["string","null"]},"token_hint":{"description":"4 derniers caractères du jeton (mode `token`). Le jeton et les jetons OAuth ne sont jamais renvoyés.","type":["string","null"]},"last_error":{"type":["string","null"]},"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}},"required":["sync_enabled","sync_on","create_deal_on_positive","deal_stage","status_map"],"additionalProperties":false,"description":"Réglages de synchronisation (valeurs par défaut du CRM si non connecté)."},"oauth_available":{"type":"boolean","description":"L'application OAuth Replexa de ce CRM est configurée sur l'instance."},"token_available":{"type":"boolean","description":"Connexion par jeton possible (HubSpot, Pipedrive ; jamais Salesforce)."},"redirect_uri":{"type":"string","format":"uri","description":"Adresse de retour OAuth de ce CRM sur cette instance."}},"required":["provider","connected","status","mode","account_email","account_name","token_hint","last_error","settings","oauth_available","token_available","redirect_uri"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/crm/hubspot\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postIntegrationsCrmByProvider","tags":["Intégrations"],"summary":"Connecter un CRM par jeton","description":"Connexion sans OAuth : HubSpot avec le jeton d'une application privée, Pipedrive avec un jeton d'API personnel. Salesforce se connecte uniquement par OAuth (depuis l'interface) et répond 400. Le jeton est d'abord vérifié par une lecture du compte, puis enregistré chiffré en remplaçant la connexion existante de ce CRM. Si le CRM refuse le jeton (401 ou 403), la route répond 400 avec le message du CRM ; s'il est en panne ou renvoie une autre erreur, 502. Dans les deux cas, rien n'est enregistré et une connexion existante reste intacte. Les réglages de synchronisation existants sont conservés, sinon ceux par défaut s'appliquent. L'action est inscrite au journal d'audit.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"workspaces:update","x-min-role":"admin","x-rate-limit":"20/min","parameters":[{"name":"provider","in":"path","required":true,"description":"CRM concerné. Toute autre valeur répond 404.","schema":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"example":"hubspot"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTokenConnect"},"example":{"token":"pat-eu1-00000000-0000-0000-0000-000000000000"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmIntegration"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/integrations/crm/hubspot\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"token\": \"pat-eu1-00000000-0000-0000-0000-000000000000\"\n}'"}]},"put":{"operationId":"putIntegrationsCrmByProvider","tags":["Intégrations"],"summary":"Tester la connexion d'un CRM","description":"Vérifie que la connexion fonctionne en lançant une recherche dans le CRM (bouton « Tester » de l'interface). Ne synchronise rien et ne modifie rien. Une requête contenant `@` cherche l'email exact, sinon une recherche libre est faite ; au plus 5 fiches sont renvoyées. Répond 400 si le CRM n'est pas connecté, 502 s'il renvoie une erreur (jeton expiré ou révoqué, droits insuffisants, panne).\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"workspaces:update","x-min-role":"admin","x-rate-limit":"20/min","parameters":[{"name":"provider","in":"path","required":true,"description":"CRM concerné. Toute autre valeur répond 404.","schema":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"example":"hubspot"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTestSearch"},"example":{"query":"jeanne@exemple.fr"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CrmContact"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PUT \"https://app.replexa.eu/api/v2/integrations/crm/hubspot\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"query\": \"jeanne@exemple.fr\"\n}'"}]},"patch":{"operationId":"patchIntegrationsCrmByProvider","tags":["Intégrations"],"summary":"Modifier la synchronisation d'un CRM","description":"Fusionne les champs fournis avec les réglages enregistrés et renvoie les réglages complets. `status_map`, s'il est fourni, remplace toute la correspondance ; les entrées à valeur vide sont retirées. Répond 400 si le CRM n'a jamais été connecté.\n\nLa synchronisation est automatique, par une tâche de fond par CRM : au premier envoi à un lead (fiche créée seulement si `sync_on` vaut `contacted`), à sa première réponse et à chaque changement de statut d'intérêt. La fiche est retrouvée par email ou créée, son statut mis à jour selon `status_map` (Pipedrive reçoit une note), et une affaire est créée au premier statut positif si `create_deal_on_positive` est actif, puis marquée gagnée ou perdue selon le statut.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","parameters":[{"name":"provider","in":"path","required":true,"description":"CRM concerné. Toute autre valeur répond 404.","schema":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"example":"hubspot"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSettingsPatch"},"example":{"settings":{"sync_on":"contacted","create_deal_on_positive":true,"status_map":{"contacted":"ATTEMPTED_TO_CONTACT","replied":"CONNECTED"}}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}},"required":["sync_enabled","sync_on","create_deal_on_positive","deal_stage","status_map"],"additionalProperties":false}},"required":["settings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/integrations/crm/hubspot\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"settings\": {\n    \"sync_on\": \"contacted\",\n    \"create_deal_on_positive\": true,\n    \"status_map\": {\n      \"contacted\": \"ATTEMPTED_TO_CONTACT\",\n      \"replied\": \"CONNECTED\"\n    }\n  }\n}'"}]},"delete":{"operationId":"deleteIntegrationsCrmByProvider","tags":["Intégrations"],"summary":"Déconnecter un CRM","description":"Supprime la connexion (jetons et réglages) et les liens entre leads et fiches du CRM : après reconnexion, les fiches sont retrouvées par email ou recréées. Les agents IA qui utilisaient ce CRM le perdent de leurs intégrations. Les jetons OAuth ne sont pas révoqués chez le CRM. L'action est inscrite au journal d'audit. Sans effet si le CRM n'était pas connecté.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","parameters":[{"name":"provider","in":"path","required":true,"description":"CRM concerné. Toute autre valeur répond 404.","schema":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"example":"hubspot"}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/integrations/crm/hubspot\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/google-calendar":{"get":{"operationId":"getIntegrationsGoogleCalendar","tags":["Intégrations"],"summary":"Lire l'intégration Google Agenda","description":"État de la connexion Google Agenda et réglages de prise de rendez-vous utilisés par les agents IA. `redirect_uri` est l'adresse de retour OAuth à déclarer dans Google Cloud. Le secret client et les jetons OAuth ne sont jamais renvoyés.\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"configured":{"type":"boolean","description":"Une application Google (ID client et secret) est disponible, celle du workspace ou celle de l'instance."},"connected":{"type":"boolean","description":"L'intégration est utilisable (statut `connected` et jeton présent)."},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"account_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}],"description":"Compte connecté côté service."},"last_error":{"type":["string","null"]},"public_config":{"type":"object","properties":{"client_id":{"type":"string"}},"additionalProperties":false,"description":"ID client enregistré. Le secret et les jetons OAuth ne sont jamais renvoyés."},"settings":{"anyOf":[{"type":"object","properties":{"calendar_id":{"type":"string","minLength":1,"description":"Agenda où les rendez-vous sont créés (`primary` ou un identifiant de `GET /integrations/google-calendar/calendars`)."},"timezone":{"type":"string","description":"Fuseau IANA des horaires (ex. `Europe/Luxembourg`)."},"days":{"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6},"description":"Jours proposés, 0 = dimanche … 6 = samedi."},"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Début de la plage horaire (HH:MM)."},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Fin de la plage horaire (HH:MM), après `from`."},"duration_minutes":{"type":"integer","minimum":10,"maximum":240,"description":"Durée d'un rendez-vous."},"buffer_minutes":{"type":"integer","minimum":0,"maximum":120,"description":"Marge laissée libre avant et après chaque évènement existant."},"min_notice_hours":{"type":"number","minimum":0,"maximum":336,"description":"Délai minimum avant le premier créneau proposé."},"max_days_ahead":{"type":"integer","minimum":1,"maximum":60,"description":"Horizon maximum des créneaux proposés, en jours."},"add_meet":{"type":"boolean","description":"Ajouter un lien Google Meet au rendez-vous."},"title_template":{"type":"string","maxLength":200,"description":"Titre du rendez-vous, variables du lead acceptées (`{{companyName}}`…)."},"description_template":{"type":"string","maxLength":2000,"description":"Description du rendez-vous, variables du lead acceptées."},"check_calendars":{"type":"array","items":{"type":"string"},"description":"Agendas supplémentaires dont les évènements bloquent aussi des créneaux."}},"required":["calendar_id","timezone","days","from","to","duration_minutes","buffer_minutes","min_notice_hours","max_days_ahead","add_meet","title_template","description_template","check_calendars"],"additionalProperties":false},{"type":"null"}],"description":"Réglages de prise de rendez-vous, `null` si rien n'est enregistré."},"redirect_uri":{"type":"string","format":"uri","description":"Adresse de retour OAuth à déclarer dans l'application Google Cloud."}},"required":["configured","connected","status","account_email","last_error","public_config","settings","redirect_uri"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/google-calendar\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchIntegrationsGoogleCalendar","tags":["Intégrations"],"summary":"Modifier les réglages de rendez-vous","description":"Fusionne les champs fournis avec les réglages enregistrés (jours, plage horaire, durée, marges, agenda cible, modèles de titre et de description) et renvoie les réglages complets. Répond 400 si aucun identifiant Google n'a été enregistré (`PUT /integrations/google-calendar/credentials`) ou si `to` n'est pas après `from`.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleCalendarSettingsPatch"},"example":{"settings":{"timezone":"Europe/Paris","days":[1,2,3,4],"from":"09:30","to":"17:30","duration_minutes":30,"add_meet":true}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"settings":{"type":"object","properties":{"calendar_id":{"type":"string","minLength":1,"description":"Agenda où les rendez-vous sont créés (`primary` ou un identifiant de `GET /integrations/google-calendar/calendars`)."},"timezone":{"type":"string","description":"Fuseau IANA des horaires (ex. `Europe/Luxembourg`)."},"days":{"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6},"description":"Jours proposés, 0 = dimanche … 6 = samedi."},"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Début de la plage horaire (HH:MM)."},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Fin de la plage horaire (HH:MM), après `from`."},"duration_minutes":{"type":"integer","minimum":10,"maximum":240,"description":"Durée d'un rendez-vous."},"buffer_minutes":{"type":"integer","minimum":0,"maximum":120,"description":"Marge laissée libre avant et après chaque évènement existant."},"min_notice_hours":{"type":"number","minimum":0,"maximum":336,"description":"Délai minimum avant le premier créneau proposé."},"max_days_ahead":{"type":"integer","minimum":1,"maximum":60,"description":"Horizon maximum des créneaux proposés, en jours."},"add_meet":{"type":"boolean","description":"Ajouter un lien Google Meet au rendez-vous."},"title_template":{"type":"string","maxLength":200,"description":"Titre du rendez-vous, variables du lead acceptées (`{{companyName}}`…)."},"description_template":{"type":"string","maxLength":2000,"description":"Description du rendez-vous, variables du lead acceptées."},"check_calendars":{"type":"array","items":{"type":"string"},"description":"Agendas supplémentaires dont les évènements bloquent aussi des créneaux."}},"required":["calendar_id","timezone","days","from","to","duration_minutes","buffer_minutes","min_notice_hours","max_days_ahead","add_meet","title_template","description_template","check_calendars"],"additionalProperties":false}},"required":["settings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/integrations/google-calendar\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"settings\": {\n    \"timezone\": \"Europe/Paris\",\n    \"days\": [\n      1,\n      2,\n      3,\n      4\n    ],\n    \"from\": \"09:30\",\n    \"to\": \"17:30\",\n    \"duration_minutes\": 30,\n    \"add_meet\": true\n  }\n}'"}]},"delete":{"operationId":"deleteIntegrationsGoogleCalendar","tags":["Intégrations"],"summary":"Déconnecter Google Agenda","description":"Révoque l'accès auprès de Google et efface les jetons OAuth et le compte connecté. L'application Google (ID client et secret) et les réglages sont conservés pour une reconnexion rapide depuis l'interface. Les agents IA qui utilisaient Google Agenda le perdent de leurs intégrations. Sans effet si rien n'était enregistré.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/integrations/google-calendar\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/google-calendar/calendars":{"get":{"operationId":"getIntegrationsGoogleCalendarCalendars","tags":["Intégrations"],"summary":"Lister les agendas Google","description":"Agendas visibles par le compte Google connecté (jusqu'à 100), lus en direct chez Google. Répond 400 si Google Agenda n'est pas connecté, 502 si Google renvoie une erreur (accès révoqué, panne).\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/GoogleCalendar"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/google-calendar/calendars\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/integrations/google-calendar/credentials":{"put":{"operationId":"putIntegrationsGoogleCalendarCredentials","tags":["Intégrations"],"summary":"Enregistrer l'application Google","description":"Enregistre, chiffrés, l'ID client et le secret de l'application OAuth Google Cloud du workspace. C'est l'étape préalable à la connexion OAuth, qui se fait ensuite depuis l'interface. Avec un ID client différent du précédent, les jetons existants sont effacés et l'intégration repasse à `disconnected`. Le secret n'est jamais renvoyé.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleCalendarCredentials"},"example":{"client_id":"123456789012-exemple.apps.googleusercontent.com","client_secret":"exemple-secret-client"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"client_id":{"type":"string"}},"required":["success","client_id"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PUT \"https://app.replexa.eu/api/v2/integrations/google-calendar/credentials\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"client_id\": \"123456789012-exemple.apps.googleusercontent.com\",\n  \"client_secret\": \"exemple-secret-client\"\n}'"}]}},"/integrations/google-calendar/slots":{"get":{"operationId":"getIntegrationsGoogleCalendarSlots","tags":["Intégrations"],"summary":"Prévisualiser les créneaux libres","description":"Créneaux qu'un agent IA proposerait maintenant : agenda cible et `check_calendars` interrogés en direct chez Google, réglages de rendez-vous appliqués (jours, plage horaire, durée, marges, délai minimum, horizon), au plus 3 créneaux par jour. Répond 400 si `limit` n'est pas un entier entre 1 et 50 ou si Google Agenda n'est pas connecté, 502 si Google renvoie une erreur (accès révoqué, panne).\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","parameters":[{"name":"limit","in":"query","required":false,"description":"Nombre maximum de créneaux, de 1 à 50 (défaut 9).","schema":{"type":"integer"},"example":9}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CalendarSlot"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/integrations/google-calendar/slots?limit=9\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/webhooks":{"get":{"operationId":"getWebhooks","tags":["Webhooks"],"summary":"Lister les webhooks","description":"Webhooks du workspace, des plus récents aux plus anciens, abonnements REST Hooks (Zapier, Make) compris. Le secret de signature n'est jamais renvoyé.\n\n**Scope** : `webhooks:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:read","x-min-role":"admin","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"campaign","in":"query","required":false,"description":"Seulement les webhooks limités à cette campagne.","schema":{"type":"string","format":"uuid"}},{"name":"event_type","in":"query","required":false,"description":"Type d'évènement exact (`reply_received`, `all_events`…).","schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/webhooks?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"post":{"operationId":"postWebhooks","tags":["Webhooks"],"summary":"Créer un webhook","description":"Crée un webhook actif qui recevra en POST JSON chaque évènement correspondant. Il faut `event_type` ou `custom_interest_value`, sinon 400. `all_events` reçoit tous les évènements ; `campaign` limite aux évènements de cette campagne (400 si elle n'existe pas). Pour un label personnalisé, laissez `event_type` vide et donnez sa valeur dans `custom_interest_value` (voir `GET /webhooks/event-types`). `headers` est ajouté à chaque livraison, par exemple un jeton attendu par votre serveur ; il ne peut remplacer ni `Content-Type`, ni `User-Agent`, ni les en-têtes `X-Replexa-*` (ignorés quelle que soit la casse).\n\nLa réponse contient `signing_secret`, **renvoyé uniquement ici** : conservez-le. Aucune route ne le relit ni ne le régénère (supprimez et recréez le webhook pour en changer).\n\n`target_hook_url` est vérifiée dès la création, avec les règles de la livraison : URL http(s) publique (le nom d'hôte doit se résoudre uniquement vers des adresses publiques, aucune adresse privée ou locale), sans identifiants intégrés, en https en production. Sinon 400 avec la raison. Vérifiez ensuite la réception avec `POST /webhooks/{id}/test`.\n\n**Signature** : chaque livraison porte `X-Replexa-Timestamp` (secondes Unix) et `X-Replexa-Signature`, le HMAC-SHA256 en hexadécimal de `{timestamp}.{corps brut}` calculé avec `signing_secret`. Recalculez-le sur le corps reçu, avant tout parsing JSON, et comparez en temps constant. Replexa ne contrôle pas l'âge de l'horodatage pour vous : rejetez par exemple les livraisons de plus de 5 minutes. L'horodatage et la signature changent à chaque tentative.\n\n**En-têtes** : `Content-Type: application/json`, `User-Agent: Replexa-Webhooks/1.0`, `X-Replexa-Timestamp`, `X-Replexa-Signature` et `X-Replexa-Event-Id`, identifiant de l'évènement (`id` de `GET /webhook-events`), identique à chaque nouvelle tentative du même évènement : servez-vous-en pour ignorer les doublons. Les en-têtes de `headers` s'y ajoutent ; ceux qui portent l'un de ces noms, quelle que soit la casse, sont ignorés.\n\n**Livraison** : le worker envoie les évènements en file toutes les 10 secondes environ, en POST JSON (délai d'expiration 15 s, redirections non suivies). Seule une réponse 2xx est un succès. Après un échec (autre code, délai dépassé, erreur réseau, adresse refusée), 5 nouvelles tentatives ont lieu 1 min, 5 min, 30 min, 2 h puis 12 h après la précédente, soit 6 tentatives au plus. Quand 20 évènements du webhook mis en file sur les dernières 24 h ont épuisé leurs tentatives (les livraisons abandonnées parce que le webhook était déjà désactivé ne comptent pas), le webhook passe en erreur (`status` -1) : il ne reçoit plus d'évènement et ses tentatives en attente sont abandonnées jusqu'à `POST /webhooks/{id}/resume`.\n\n**Scope** : `webhooks:create` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:create","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"},"example":{"name":"Réponses vers le CRM","target_hook_url":"https://hooks.exemple.fr/replexa","event_type":"reply_received","headers":{"Authorization":"Bearer jeton-de-votre-serveur"}}}}},"responses":{"200":{"description":"Webhook créé, avec son secret de signature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithSecret"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/webhooks\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Réponses vers le CRM\",\n  \"target_hook_url\": \"https://hooks.exemple.fr/replexa\",\n  \"event_type\": \"reply_received\",\n  \"headers\": {\n    \"Authorization\": \"Bearer jeton-de-votre-serveur\"\n  }\n}'"}]}},"/webhooks/{id}":{"get":{"operationId":"getWebhooksById","tags":["Webhooks"],"summary":"Lire un webhook","description":"Réglages et état du webhook (`status` 1 actif, -1 en erreur). Le secret de signature n'est jamais renvoyé.\n\n**Scope** : `webhooks:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:read","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du webhook (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/webhooks/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchWebhooksById","tags":["Webhooks"],"summary":"Modifier un webhook","description":"Met à jour les champs fournis (nom, URL, campagne, évènement, valeur de label, en-têtes). `headers`, s'il est fourni, remplace tous les en-têtes. Le secret de signature et le statut ne changent pas : un webhook en erreur se réactive avec `POST /webhooks/{id}/resume`. La règle « `event_type` ou `custom_interest_value` » est vérifiée sur le résultat fusionné (400 si les deux finissent vides). Une nouvelle `target_hook_url` est vérifiée comme à la création (URL publique, https en production), sinon 400.\n\n**Scope** : `webhooks:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:update","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du webhook (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookPatch"},"example":{"target_hook_url":"https://hooks.exemple.fr/replexa-v2","event_type":"all_events"}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/webhooks/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"target_hook_url\": \"https://hooks.exemple.fr/replexa-v2\",\n  \"event_type\": \"all_events\"\n}'"}]},"delete":{"operationId":"deleteWebhooksById","tags":["Webhooks"],"summary":"Supprimer un webhook","description":"Supprime le webhook, ses livraisons en attente et son journal de livraison. Renvoie le webhook supprimé (sans son secret). Fonctionne aussi pour un abonnement REST Hooks.\n\n**Scope** : `webhooks:delete` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:delete","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du webhook (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook supprimé.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/webhooks/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/webhooks/{id}/resume":{"post":{"operationId":"postWebhooksByIdResume","tags":["Webhooks"],"summary":"Réactiver un webhook","description":"Repasse le webhook à l'état actif (`status` 1) et efface `timestamp_error`, par exemple après sa désactivation automatique pour trop d'échecs. Seuls les nouveaux évènements sont livrés : les livraisons abandonnées pendant la désactivation ne sont pas rejouées. Sans effet sur un webhook déjà actif. Renvoie le webhook.\n\n**Scope** : `webhooks:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:update","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du webhook (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/webhooks/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/resume\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/webhooks/{id}/test":{"post":{"operationId":"postWebhooksByIdTest","tags":["Webhooks"],"summary":"Tester un webhook","description":"Envoie immédiatement un évènement d'exemple signé à l'URL du webhook, avec ses en-têtes, et renvoie le résultat. Le payload contient `test: true`, `lead_email: \"test@example.com\"` et `campaign_name: \"Test\"` ; son `event_type` est celui du webhook (`custom_label` pour un label personnalisé). Une seule tentative, avec `X-Replexa-Event-Id: test` ; rien n'est inscrit au journal (`GET /webhook-events`) et le statut du webhook ne change pas, même en cas d'échec. Fonctionne aussi sur un webhook en erreur.\n\n**Scope** : `webhooks:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 20 requêtes par minute (action sensible)","x-scope":"webhooks:update","x-min-role":"admin","x-rate-limit":"20/min","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant du webhook (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"`true` si l'URL a répondu 2xx."},"message":{"type":"string","description":"« Webhook livré » ou « Échec de la livraison »."},"response_time_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Code HTTP reçu, `null` sans réponse."},"error":{"description":"Cause de l'échec (code et début de la réponse, délai dépassé, adresse refusée…).","type":["string","null"]}},"required":["success","message","response_time_ms","status_code","error"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/webhooks/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90/test\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/webhooks/event-types":{"get":{"operationId":"getWebhooksEventTypes","tags":["Webhooks"],"summary":"Lister les types d'évènements","description":"Évènements utilisables dans `event_type` : les évènements standard (`email_sent`, `email_opened`, `email_link_clicked`, `reply_received`, `auto_reply_received`, `email_bounced`, `lead_unsubscribed`, `campaign_completed`, `account_error`, les statuts d'intérêt de `lead_neutral` à `lead_no_show`, et `ai_draft_created`), puis `custom_label_any_positive` et `custom_label_any_negative`, puis un élément par label personnalisé du workspace. Pour ces derniers, `id` est le nom du label : abonnez-vous avec `custom_interest_value` (et `event_type` vide), pas avec ce nom. `all_events`, accepté à la création, n'est pas listé.\n\n**Scope** : `webhooks:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:read","x-min-role":"admin","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"event_types":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Valeur de `event_type`, ou nom du label personnalisé."},"label":{"type":"string","description":"Libellé (en anglais)."},"type":{"type":"string","enum":["standard","custom_label"]},"custom_interest_value":{"description":"Labels personnalisés : valeur à donner dans `custom_interest_value`.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","label","type"],"additionalProperties":false}}},"required":["event_types"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/webhooks/event-types\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/hooks/me":{"get":{"operationId":"getHooksMe","tags":["REST Hooks"],"summary":"Tester la clé API","description":"Test de connexion utilisé par Zapier et Make : renvoie le workspace et le rôle associés à la clé. Aucun effet de bord.\n\n**Scope** : `webhooks:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:read","x-min-role":"admin","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"workspace_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace de la clé."},"workspace_name":{"type":["string","null"]},"role":{"type":"string","enum":["viewer","member","admin","owner"],"description":"Rôle de la clé dans le workspace."}},"required":["workspace_id","workspace_name","role"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/hooks/me\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/hooks/sample":{"get":{"operationId":"getHooksSample","tags":["REST Hooks"],"summary":"Obtenir un exemple de payload","description":"Exemple de payload au format des vraies livraisons, pour que Zapier ou Make connaissent les champs avant le premier évènement. Renvoie un **tableau** d'un élément (format attendu par Zapier), avec `id: \"sample\"` et `reply_text`. Les données sont fictives et ne dépendent pas du workspace, hormis `workspace`. Répond 400 pour un évènement inconnu.\n\n**Scope** : `webhooks:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:read","x-min-role":"admin","parameters":[{"name":"event","in":"query","required":false,"description":"`all_events` ou un évènement standard de `GET /webhooks/event-types` (défaut `reply_received`). Les évènements `custom_label_any_*` ne sont pas acceptés.","schema":{"type":"string"},"example":"reply_received"}],"responses":{"200":{"description":"Tableau contenant un payload d'exemple.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de l'évènement."},"event_type":{"type":"string","description":"Type d'évènement (`GET /webhooks/event-types`), ou `custom_label` pour un label personnalisé."},"workspace":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace concerné."},"campaign_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"campaign_name":{"type":["string","null"]},"is_first":{"type":"boolean","description":"Premier évènement de ce type pour ce lead."},"lead_email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"email_account":{"description":"Boîte d'envoi concernée.","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"step":{"description":"Étape de la séquence, à partir de 1.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"variant":{"description":"Variante de l'étape, à partir de 1.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"custom_interest_value":{"description":"Valeur du label personnalisé (évènement `custom_label`).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email_subject":{"description":"Email envoyé : objet (`email_text` et `email_html` pour le corps).","type":"string"},"reply_subject":{"description":"Réponse reçue : objet (`reply_text`, `reply_html`, `reply_text_snippet` et `unibox_url` l'accompagnent).","type":"string"},"reply_text":{"type":"string"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"companyName":{"type":["string","null"]},"website":{"type":["string","null"]},"phone":{"type":["string","null"]},"personalization":{"type":["string","null"]},"id":{"type":"string","const":"sample"}},"required":["timestamp","event_type","workspace","campaign_id","campaign_name","is_first","id"],"additionalProperties":{}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/hooks/sample?event=reply_received\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/hooks/subscribe":{"post":{"operationId":"postHooksSubscribe","tags":["REST Hooks"],"summary":"S'abonner à un évènement","description":"Abonnement REST Hooks (Zapier, Make, applications tierces) : crée un webhook signé vers `target_url` (ou `hookUrl`, nom utilisé par Zapier), nommé `{source} · {event}` et marqué par sa `source`. Il fonctionne comme un webhook classique et apparaît dans `GET /webhooks`. Conservez `id` pour vous désabonner avec `DELETE /hooks/{id}`. Répond 400 sans URL cible, si l'URL n'est pas publique (adresse privée ou locale, http en production ; mêmes règles que `POST /webhooks`) ou si `campaign` n'existe pas.\n\nLa réponse contient `signing_secret`, renvoyé uniquement ici. Une cible qui répond `410 Gone` à une livraison est désabonnée automatiquement (webhook et journal supprimés).\n\n**Signature** : chaque livraison porte `X-Replexa-Timestamp` (secondes Unix) et `X-Replexa-Signature`, le HMAC-SHA256 en hexadécimal de `{timestamp}.{corps brut}` calculé avec `signing_secret`. Recalculez-le sur le corps reçu, avant tout parsing JSON, et comparez en temps constant. Replexa ne contrôle pas l'âge de l'horodatage pour vous : rejetez par exemple les livraisons de plus de 5 minutes. L'horodatage et la signature changent à chaque tentative.\n\n**En-têtes** : `Content-Type: application/json`, `User-Agent: Replexa-Webhooks/1.0`, `X-Replexa-Timestamp`, `X-Replexa-Signature` et `X-Replexa-Event-Id`, identifiant de l'évènement (`id` de `GET /webhook-events`), identique à chaque nouvelle tentative du même évènement : servez-vous-en pour ignorer les doublons. Les en-têtes de `headers` s'y ajoutent ; ceux qui portent l'un de ces noms, quelle que soit la casse, sont ignorés.\n\n**Livraison** : le worker envoie les évènements en file toutes les 10 secondes environ, en POST JSON (délai d'expiration 15 s, redirections non suivies). Seule une réponse 2xx est un succès. Après un échec (autre code, délai dépassé, erreur réseau, adresse refusée), 5 nouvelles tentatives ont lieu 1 min, 5 min, 30 min, 2 h puis 12 h après la précédente, soit 6 tentatives au plus. Quand 20 évènements du webhook mis en file sur les dernières 24 h ont épuisé leurs tentatives (les livraisons abandonnées parce que le webhook était déjà désactivé ne comptent pas), le webhook passe en erreur (`status` -1) : il ne reçoit plus d'évènement et ses tentatives en attente sont abandonnées jusqu'à `POST /webhooks/{id}/resume`.\n\n**Scope** : `webhooks:create` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:create","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestHookSubscribe"},"example":{"hookUrl":"https://hooks.zapier.com/hooks/standard/123456/abcdef/","event":"lead_interested","source":"zapier"}}}},"responses":{"200":{"description":"Abonnement créé, avec son secret de signature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithSecret"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X POST \"https://app.replexa.eu/api/v2/hooks/subscribe\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"hookUrl\": \"https://hooks.zapier.com/hooks/standard/123456/abcdef/\",\n  \"event\": \"lead_interested\",\n  \"source\": \"zapier\"\n}'"}]}},"/hooks/{id}":{"delete":{"operationId":"deleteHooksById","tags":["REST Hooks"],"summary":"Se désabonner","description":"Supprime un abonnement créé par `POST /hooks/subscribe`, avec ses livraisons en attente et son journal. Un webhook créé par `POST /webhooks` ou dans l'interface (`source: \"manual\"`) n'est pas concerné et répond 404 : supprimez-le avec `DELETE /webhooks/{id}`.\n\n**Scope** : `webhooks:delete` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhooks:delete","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'abonnement (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["success","id"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/hooks/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/webhook-events":{"get":{"operationId":"getWebhookEvents","tags":["Webhooks"],"summary":"Lister les livraisons de webhooks","description":"Journal de livraison de tous les webhooks du workspace, des plus récentes aux plus anciennes : une ligne par évènement et par webhook, mise à jour à chaque tentative (code HTTP, erreur, temps de réponse, prochaine tentative). Les tests de `POST /webhooks/{id}/test` n'y figurent pas. Supprimer un webhook supprime ses lignes.\n\n**Livraison** : le worker envoie les évènements en file toutes les 10 secondes environ, en POST JSON (délai d'expiration 15 s, redirections non suivies). Seule une réponse 2xx est un succès. Après un échec (autre code, délai dépassé, erreur réseau, adresse refusée), 5 nouvelles tentatives ont lieu 1 min, 5 min, 30 min, 2 h puis 12 h après la précédente, soit 6 tentatives au plus. Quand 20 évènements du webhook mis en file sur les dernières 24 h ont épuisé leurs tentatives (les livraisons abandonnées parce que le webhook était déjà désactivé ne comptent pas), le webhook passe en erreur (`status` -1) : il ne reçoit plus d'évènement et ses tentatives en attente sont abandonnées jusqu'à `POST /webhooks/{id}/resume`.\n\n**Scope** : `webhook_events:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"webhook_events:read","x-min-role":"admin","parameters":[{"name":"limit","in":"query","required":false,"description":"Éléments par page, de 1 à 100 (défaut 10).","schema":{"type":"integer"},"example":10},{"name":"starting_after","in":"query","required":false,"description":"Curseur : la valeur `next_starting_after` de la page précédente.","schema":{"type":"string"}},{"name":"success","in":"query","required":false,"description":"`true` (ou `1`) : livraisons réussies ; toute autre valeur : livraisons pas (encore) réussies.","schema":{"type":"boolean"}},{"name":"from","in":"query","required":false,"description":"Mises en file à partir de cette date (incluse).","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Mises en file jusqu'à cette date (incluse).","schema":{"type":"string","format":"date-time"}},{"name":"search","in":"query","required":false,"description":"Filtre sur l'email du lead (contient, sans tenir compte de la casse).","schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"next_starting_after":{"type":"string","description":"Curseur de la page suivante, absent sur la dernière page."}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/webhook-events?limit=10\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/workspaces/current":{"get":{"operationId":"getWorkspacesCurrent","tags":["Workspace"],"summary":"Lire le workspace","description":"Workspace de la clé API : nom, plan et état de l'abonnement, limites propres, réglages. Les identifiants Stripe (client, abonnement) ne sont jamais renvoyés.\n\n**Scope** : `workspaces:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/workspaces/current\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]},"patch":{"operationId":"patchWorkspacesCurrent","tags":["Workspace"],"summary":"Modifier le workspace","description":"Modifie le nom et les réglages. Les clés de `settings` envoyées sont fusionnées avec les réglages existants, les autres restent inchangées. Un changement de nom est inscrit au journal d'audit. Sans changement, renvoie le workspace tel quel.\n\n`require_mfa` se règle depuis l'interface : avec une clé API ou un jeton OAuth, une valeur différente de l'actuelle renvoie 403.\n\n**Scope** : `workspaces:update` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"workspaces:update","x-min-role":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"require_mfa":{"description":"Double authentification obligatoire pour les membres. Se règle depuis l'interface : refusé avec une clé API dès que la valeur change.","type":"boolean"},"settings":{"type":"object","properties":{"auto_interest":{"type":"boolean","description":"L'IA attribue un statut d'intérêt à chaque réponse reçue."},"auto_interest_update_existing_labels":{"type":"boolean","description":"L'IA peut remplacer un statut déjà posé (jamais un statut posé à la main)."},"auto_ooo_status":{"type":"boolean","description":"Marque automatiquement les absences du bureau."},"auto_protect_campaigns":{"type":"boolean","description":"Met en pause une campagne dont le taux de bounce dépasse le seuil."},"auto_protect_campaigns_bounce_rate_threshold":{"type":"number","minimum":1,"maximum":50,"description":"Seuil de bounce en %, de 1 à 50."},"default_opportunity_value":{"type":"number","minimum":0,"description":"Valeur par défaut d'une opportunité, pour les statistiques."},"notification_recipients_positive_reply":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"description":"Adresses prévenues à chaque réponse positive."}}}}},"example":{"name":"Exemple SARL","settings":{"auto_protect_campaigns":true,"auto_protect_campaigns_bounce_rate_threshold":4}}}}},"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"413":{"$ref":"#/components/responses/E413"},"415":{"$ref":"#/components/responses/E415"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X PATCH \"https://app.replexa.eu/api/v2/workspaces/current\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"name\": \"Exemple SARL\",\n  \"settings\": {\n    \"auto_protect_campaigns\": true,\n    \"auto_protect_campaigns_bounce_rate_threshold\": 4\n  }\n}'"}]}},"/workspaces/current/invitations":{"get":{"operationId":"getWorkspacesCurrentInvitations","tags":["Workspace"],"summary":"Lister les invitations en cours","description":"Invitations encore utilisables (ni révoquées, ni expirées, ni épuisées), des plus récentes aux plus anciennes. Le lien d'invitation n'est jamais renvoyé : il n'est montré qu'à sa création, depuis l'interface (Paramètres › Workspace › Inviter). Liste complète, sans pagination.\n\n**Scope** : `invitations:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"invitations:read","x-min-role":"admin","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceInvitation"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/workspaces/current/invitations\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/workspaces/current/invitations/{id}":{"delete":{"operationId":"deleteWorkspacesCurrentInvitationsById","tags":["Workspace"],"summary":"Révoquer une invitation","description":"Rend l'invitation inutilisable (le lien ne fonctionne plus) et l'inscrit au journal d'audit. Les membres déjà arrivés par cette invitation restent membres. Répond 404 si l'invitation n'existe pas dans le workspace ; une invitation déjà révoquée renvoie un succès sans rien modifier ni journaliser.\n\n**Scope** : `invitations:delete` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"invitations:delete","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de l'invitation (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/workspaces/current/invitations/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/workspaces/current/members":{"get":{"operationId":"getWorkspacesCurrentMembers","tags":["Workspace"],"summary":"Lister les membres","description":"Membres du workspace avec leur rôle, leur email et leur nom, par date d'arrivée. Aucune autre donnée de compte n'est renvoyée. Liste complète, sans pagination.\n\n**Scope** : `members:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"members:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceMember"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/workspaces/current/members\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/api-keys":{"get":{"operationId":"getApiKeys","tags":["Clés API"],"summary":"Lister les clés API","description":"Clés actives du workspace (ni révoquées, ni expirées), des plus récentes aux plus anciennes. La clé elle-même n'est jamais renvoyée, seulement `key_prefix`. Les clés se créent dans l'application, sous Paramètres › API et webhooks. Liste complète, sans pagination.\n\n**Scope** : `api_keys:read` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"api_keys:read","x-min-role":"admin","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/api-keys\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/api-keys/{id}":{"delete":{"operationId":"deleteApiKeysById","tags":["Clés API"],"summary":"Révoquer une clé API","description":"Révoque la clé : elle est refusée (401) dès la requête suivante, y compris si c'est la clé qui fait l'appel. Elle reste dans l'historique et la révocation est inscrite au journal d'audit. Renvoie la clé révoquée. Pour en créer une nouvelle, passez par l'application (Paramètres › API et webhooks).\n\n**Scope** : `api_keys:delete` · **Rôle minimum** : administrateur (admin) · **Limite** : 600 requêtes par minute","x-scope":"api_keys:delete","x-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Identifiant de la clé (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X DELETE \"https://app.replexa.eu/api/v2/api-keys/0193f0a2-7c1e-7d4b-9a51-3f2b8c6d1e90\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}},"/billing":{"get":{"operationId":"getBilling","tags":["Facturation"],"summary":"Lire l'abonnement","description":"Plan, statut de l'abonnement, limites effectives, consommation du mois et plans proposés. Quand `sending_blocked` est true, les envois (campagnes, réponses, transferts) et les appels IA sont refusés avec 402 jusqu'à régularisation. Le changement de plan et le portail de facturation se gèrent depuis l'interface, par le propriétaire.\n\n**Scope** : `billing:read` · **Rôle minimum** : lecteur (viewer) · **Limite** : 600 requêtes par minute","x-scope":"billing:read","x-min-role":"viewer","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"400":{"$ref":"#/components/responses/E400"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"429":{"$ref":"#/components/responses/E429"}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -X GET \"https://app.replexa.eu/api/v2/billing\" \\\n  -H \"Authorization: Bearer $REPLEXA_API_KEY\""}]}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Clé API `apo_…` créée dans Paramètres › API et webhooks."},"oauth2":{"type":"oauth2","description":"OAuth 2.1 (PKCE S256 obligatoire, enregistrement dynamique des clients), utilisé par les connecteurs MCP.","flows":{"authorizationCode":{"authorizationUrl":"https://app.replexa.eu/oauth/authorize","tokenUrl":"https://app.replexa.eu/oauth/token","refreshUrl":"https://app.replexa.eu/oauth/token","scopes":{"replexa:read":"Lecture de toutes les ressources","replexa:write":"Lecture et écriture"}}}}},"schemas":{"CampaignCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1},"campaign_schedule":{"type":"object","properties":{"start_date":{"type":["string","null"]},"end_date":{"type":["string","null"]},"schedules":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"default":"Default","type":"string"},"timing":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$"},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}},"required":["from","to"]},"days":{"type":"object","propertyNames":{"type":"string","enum":["0","1","2","3","4","5","6"]},"additionalProperties":{"type":"boolean"}},"timezone":{"type":"string"}},"required":["timing","days","timezone"]}}},"required":["schedules"]},"sequences":{"minItems":1,"type":"array","items":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"type":{"default":"email","type":"string","const":"email"},"delay":{"default":0,"type":"number","minimum":0,"maximum":527040},"delay_unit":{"default":"days","type":"string","enum":["minutes","hours","days"]},"pre_delay":{"type":"number","minimum":0},"pre_delay_unit":{"type":"string","enum":["minutes","hours","days"]},"variants":{"minItems":1,"maxItems":26,"type":"array","items":{"type":"object","properties":{"subject":{"default":"","type":"string"},"body":{"default":"","type":"string"},"v_disabled":{"type":"boolean"}}}},"adv_con":{"type":"array","items":{"type":"object","properties":{"ac_trigger":{"type":"string","enum":["T_OE","T_RE"]},"ac_action":{"type":"string","enum":["A_SKIP_WAIT","A_CHANGE_WAIT"]},"ac_action_value":{"type":"number","minimum":0}},"required":["ac_trigger","ac_action"]}}},"required":["variants"]}}},"required":["steps"]}},"email_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"email_tag_list":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"daily_limit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"daily_max_leads":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"email_gap":{"type":"integer","minimum":0,"maximum":9007199254740991},"random_wait_max":{"type":"integer","minimum":0,"maximum":9007199254740991},"text_only":{"type":"boolean"},"first_email_text_only":{"type":"boolean"},"link_tracking":{"type":"boolean"},"open_tracking":{"type":"boolean"},"stop_on_reply":{"type":"boolean"},"stop_on_auto_reply":{"type":"boolean"},"stop_for_company":{"type":"boolean"},"prioritize_new_leads":{"type":"boolean"},"match_lead_esp":{"type":"boolean"},"allow_risky_contacts":{"type":"boolean"},"disable_bounce_protect":{"type":"boolean"},"insert_unsubscribe_header":{"type":"boolean"},"auto_variant_select":{"anyOf":[{"type":"object","properties":{"trigger":{"type":"string","enum":["reply_rate","click_rate","open_rate"]}},"required":["trigger"]},{"type":"null"}]},"limit_emails_per_company_override":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["custom","disabled"]},"daily_limit":{"type":"integer","minimum":1,"maximum":9007199254740991},"scope":{"type":"string","enum":["per_campaign","across_workspace"]}},"required":["mode"]},{"type":"null"}]},"provider_routing_rules":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string","enum":["send","do_not_send"]},"recipient_esp":{"type":"array","items":{"type":"string","enum":["all","google","outlook","other"]}},"sender_esp":{"type":"array","items":{"type":"string","enum":["all","google","outlook","other"]}}},"required":["action","recipient_esp","sender_esp"]}},"cc_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"bcc_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"pl_value":{"type":["number","null"]},"ai_agent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["name"]},"CampaignPatch":{"type":"object","properties":{"name":{"type":"string","minLength":1},"campaign_schedule":{"type":"object","properties":{"start_date":{"type":["string","null"]},"end_date":{"type":["string","null"]},"schedules":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"default":"Default","type":"string"},"timing":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$"},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}},"required":["from","to"]},"days":{"type":"object","propertyNames":{"type":"string","enum":["0","1","2","3","4","5","6"]},"additionalProperties":{"type":"boolean"}},"timezone":{"type":"string"}},"required":["timing","days","timezone"]}}},"required":["schedules"]},"sequences":{"minItems":1,"type":"array","items":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"type":{"default":"email","type":"string","const":"email"},"delay":{"default":0,"type":"number","minimum":0,"maximum":527040},"delay_unit":{"default":"days","type":"string","enum":["minutes","hours","days"]},"pre_delay":{"type":"number","minimum":0},"pre_delay_unit":{"type":"string","enum":["minutes","hours","days"]},"variants":{"minItems":1,"maxItems":26,"type":"array","items":{"type":"object","properties":{"subject":{"default":"","type":"string"},"body":{"default":"","type":"string"},"v_disabled":{"type":"boolean"}}}},"adv_con":{"type":"array","items":{"type":"object","properties":{"ac_trigger":{"type":"string","enum":["T_OE","T_RE"]},"ac_action":{"type":"string","enum":["A_SKIP_WAIT","A_CHANGE_WAIT"]},"ac_action_value":{"type":"number","minimum":0}},"required":["ac_trigger","ac_action"]}}},"required":["variants"]}}},"required":["steps"]}},"email_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"email_tag_list":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"daily_limit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"daily_max_leads":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"email_gap":{"type":"integer","minimum":0,"maximum":9007199254740991},"random_wait_max":{"type":"integer","minimum":0,"maximum":9007199254740991},"text_only":{"type":"boolean"},"first_email_text_only":{"type":"boolean"},"link_tracking":{"type":"boolean"},"open_tracking":{"type":"boolean"},"stop_on_reply":{"type":"boolean"},"stop_on_auto_reply":{"type":"boolean"},"stop_for_company":{"type":"boolean"},"prioritize_new_leads":{"type":"boolean"},"match_lead_esp":{"type":"boolean"},"allow_risky_contacts":{"type":"boolean"},"disable_bounce_protect":{"type":"boolean"},"insert_unsubscribe_header":{"type":"boolean"},"auto_variant_select":{"anyOf":[{"type":"object","properties":{"trigger":{"type":"string","enum":["reply_rate","click_rate","open_rate"]}},"required":["trigger"]},{"type":"null"}]},"limit_emails_per_company_override":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["custom","disabled"]},"daily_limit":{"type":"integer","minimum":1,"maximum":9007199254740991},"scope":{"type":"string","enum":["per_campaign","across_workspace"]}},"required":["mode"]},{"type":"null"}]},"provider_routing_rules":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string","enum":["send","do_not_send"]},"recipient_esp":{"type":"array","items":{"type":"string","enum":["all","google","outlook","other"]}},"sender_esp":{"type":"array","items":{"type":"string","enum":["all","google","outlook","other"]}}},"required":["action","recipient_esp","sender_esp"]}},"cc_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"bcc_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"pl_value":{"type":["number","null"]},"ai_agent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}}},"SubsequenceCreate":{"type":"object","properties":{"parent_campaign":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","minLength":1},"conditions":{"type":"object","properties":{"crm_status":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"lead_activity":{"type":"array","items":{"anyOf":[{"type":"number","const":2},{"type":"number","const":4},{"type":"number","const":91}]}},"reply_contains":{"type":"string"}}},"subsequence_schedule":{"anyOf":[{"type":"object","properties":{"start_date":{"type":["string","null"]},"end_date":{"type":["string","null"]},"schedules":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"default":"Default","type":"string"},"timing":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$"},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}},"required":["from","to"]},"days":{"type":"object","propertyNames":{"type":"string","enum":["0","1","2","3","4","5","6"]},"additionalProperties":{"type":"boolean"}},"timezone":{"type":"string"}},"required":["timing","days","timezone"]}}},"required":["schedules"]},{"type":"null"}]},"sequences":{"minItems":1,"type":"array","items":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"type":{"default":"email","type":"string","const":"email"},"delay":{"default":0,"type":"number","minimum":0,"maximum":527040},"delay_unit":{"default":"days","type":"string","enum":["minutes","hours","days"]},"pre_delay":{"type":"number","minimum":0},"pre_delay_unit":{"type":"string","enum":["minutes","hours","days"]},"variants":{"minItems":1,"maxItems":26,"type":"array","items":{"type":"object","properties":{"subject":{"default":"","type":"string"},"body":{"default":"","type":"string"},"v_disabled":{"type":"boolean"}}}},"adv_con":{"type":"array","items":{"type":"object","properties":{"ac_trigger":{"type":"string","enum":["T_OE","T_RE"]},"ac_action":{"type":"string","enum":["A_SKIP_WAIT","A_CHANGE_WAIT"]},"ac_action_value":{"type":"number","minimum":0}},"required":["ac_trigger","ac_action"]}}},"required":["variants"]}}},"required":["steps"]}},"auto_variant_select":{"anyOf":[{"type":"object","properties":{"trigger":{"type":"string","enum":["reply_rate","click_rate","open_rate"]}},"required":["trigger"]},{"type":"null"}]},"daily_limit_mode":{"type":"string","enum":["inherit","custom","unlimited"]},"daily_limit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"ignore_account_daily_limit":{"type":"boolean"}},"required":["parent_campaign","name","conditions","sequences"]},"SubsequencePatch":{"type":"object","properties":{"name":{"type":"string","minLength":1},"conditions":{"type":"object","properties":{"crm_status":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"lead_activity":{"type":"array","items":{"anyOf":[{"type":"number","const":2},{"type":"number","const":4},{"type":"number","const":91}]}},"reply_contains":{"type":"string"}}},"subsequence_schedule":{"anyOf":[{"type":"object","properties":{"start_date":{"type":["string","null"]},"end_date":{"type":["string","null"]},"schedules":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"default":"Default","type":"string"},"timing":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$"},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}},"required":["from","to"]},"days":{"type":"object","propertyNames":{"type":"string","enum":["0","1","2","3","4","5","6"]},"additionalProperties":{"type":"boolean"}},"timezone":{"type":"string"}},"required":["timing","days","timezone"]}}},"required":["schedules"]},{"type":"null"}]},"sequences":{"minItems":1,"type":"array","items":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"type":{"default":"email","type":"string","const":"email"},"delay":{"default":0,"type":"number","minimum":0,"maximum":527040},"delay_unit":{"default":"days","type":"string","enum":["minutes","hours","days"]},"pre_delay":{"type":"number","minimum":0},"pre_delay_unit":{"type":"string","enum":["minutes","hours","days"]},"variants":{"minItems":1,"maxItems":26,"type":"array","items":{"type":"object","properties":{"subject":{"default":"","type":"string"},"body":{"default":"","type":"string"},"v_disabled":{"type":"boolean"}}}},"adv_con":{"type":"array","items":{"type":"object","properties":{"ac_trigger":{"type":"string","enum":["T_OE","T_RE"]},"ac_action":{"type":"string","enum":["A_SKIP_WAIT","A_CHANGE_WAIT"]},"ac_action_value":{"type":"number","minimum":0}},"required":["ac_trigger","ac_action"]}}},"required":["variants"]}}},"required":["steps"]}},"auto_variant_select":{"anyOf":[{"type":"object","properties":{"trigger":{"type":"string","enum":["reply_rate","click_rate","open_rate"]}},"required":["trigger"]},{"type":"null"}]},"daily_limit_mode":{"type":"string","enum":["inherit","custom","unlimited"]},"daily_limit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"ignore_account_daily_limit":{"type":"boolean"}}},"LeadAiConfig":{"type":"object","properties":{"template":{"type":"string","enum":["company_name","first_name","salutation","icebreaker","custom"]},"prompt":{"type":"string","maxLength":2000},"target":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"field"},"name":{"type":"string","enum":["first_name","last_name","company_name","job_title","website","personalization"]}},"required":["kind","name"]},{"type":"object","properties":{"kind":{"type":"string","const":"variable"},"name":{"type":"string","minLength":1,"maxLength":40}},"required":["kind","name"]}]},"read_website":{"type":"boolean"}},"required":["template","target"]},"LeadListWrite":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Nom de la liste."}},"required":["name"]},"AccountCreate":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"default":"","type":"string"},"last_name":{"default":"","type":"string"},"provider_code":{"default":1,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"smtp_port":{"default":587,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_username":{"type":"string","minLength":1},"smtp_password":{"type":"string","minLength":1},"smtp_secure":{"type":"boolean"},"imap_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"imap_port":{"default":993,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"imap_username":{"type":"string","minLength":1},"imap_password":{"type":"string","minLength":1},"daily_limit":{"default":30,"type":"integer","minimum":1,"maximum":9007199254740991},"sending_gap":{"default":10,"type":"integer","minimum":0,"maximum":1440},"enable_slow_ramp":{"type":"boolean"},"signature":{"type":["string","null"]},"reply_to":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"tracking_domain_name":{"anyOf":[{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"warmup":{"type":"object","properties":{"enabled":{"type":"boolean"},"limit":{"type":"integer","minimum":1,"maximum":200},"increment":{"type":"integer","minimum":0,"maximum":4},"reply_rate":{"type":"number","minimum":0,"maximum":100},"slow_warmup_disabled":{"type":"boolean"},"filter_tag":{"type":["string","null"]},"advanced":{"type":"object","properties":{"weekday_only":{"type":"boolean"},"read_emulation":{"type":"boolean"},"warm_ctd":{"type":"boolean"},"open_rate":{"type":"number","minimum":0,"maximum":100},"spam_save_rate":{"type":"number","minimum":0,"maximum":100},"important_rate":{"type":"number","minimum":0,"maximum":100}},"required":["weekday_only","read_emulation","warm_ctd","open_rate","spam_save_rate","important_rate"]}}},"inbox_placement_test_limit":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["email","smtp_host","smtp_username","smtp_password","imap_host","imap_username","imap_password"]},"AccountPatch":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"provider_code":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"smtp_port":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_username":{"type":"string","minLength":1},"smtp_password":{"type":"string","minLength":1},"smtp_secure":{"type":"boolean"},"imap_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"imap_port":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"imap_username":{"type":"string","minLength":1},"imap_password":{"type":"string","minLength":1},"daily_limit":{"type":"integer","minimum":1,"maximum":9007199254740991},"sending_gap":{"type":"integer","minimum":0,"maximum":1440},"enable_slow_ramp":{"type":"boolean"},"signature":{"type":["string","null"]},"reply_to":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"tracking_domain_name":{"anyOf":[{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"warmup":{"type":"object","properties":{"enabled":{"type":"boolean"},"limit":{"type":"integer","minimum":1,"maximum":200},"increment":{"type":"integer","minimum":0,"maximum":4},"reply_rate":{"type":"number","minimum":0,"maximum":100},"slow_warmup_disabled":{"type":"boolean"},"filter_tag":{"type":["string","null"]},"advanced":{"type":"object","properties":{"weekday_only":{"type":"boolean"},"read_emulation":{"type":"boolean"},"warm_ctd":{"type":"boolean"},"open_rate":{"type":"number","minimum":0,"maximum":100},"spam_save_rate":{"type":"number","minimum":0,"maximum":100},"important_rate":{"type":"number","minimum":0,"maximum":100}},"required":["weekday_only","read_emulation","warm_ctd","open_rate","spam_save_rate","important_rate"]}}},"inbox_placement_test_limit":{"type":"integer","minimum":0,"maximum":9007199254740991}}},"EmailReply":{"type":"object","properties":{"eaccount":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"reply_to_uuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reyply_to_uuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"subject":{"type":"string"},"body":{"type":"object","properties":{"html":{"type":"string"},"text":{"type":"string"}}},"cc_address_email_list":{"type":"string"},"bcc_address_email_list":{"type":"string"},"additional_recipients":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}}},"required":["eaccount","body"]},"AiAgentCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Nom de l'agent."},"mode":{"type":"string","enum":["off","human_in_loop","autopilot"],"description":"`off` : classe les réponses sans rédiger. `human_in_loop` (défaut) : brouillons à valider. `autopilot` : envoi automatique après `reply_delay_minutes`, sauf cas qui exigent une validation."},"status":{"type":"integer","minimum":0,"maximum":1,"description":"1 actif (défaut), 0 inactif. Un agent inactif ne traite aucune réponse."},"instructions":{"type":"string","description":"Rôle et consignes générales de l'agent."},"knowledge":{"type":"string","description":"Connaissances mises à disposition : offre, prix, FAQ, réponses aux objections."},"booking_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Lien de prise de rendez-vous donné au prospect. Sans lien, l'agent propose des créneaux."},"signature":{"description":"Signature de l'agent (enregistrée telle quelle ; les réponses envoyées reçoivent la signature de la boîte d'envoi).","type":["string","null"]},"language":{"type":"string","description":"Langue des réponses : `auto` (défaut, langue du prospect) ou une langue explicite (`fr`, `en`...)."},"reply_delay_minutes":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Délai avant l'envoi automatique d'une réponse en autopilot, en minutes (défaut 15)."},"escalate_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt du lead pour lesquels le brouillon passe toujours en validation humaine (défaut `[-1, -2]`)."},"campaign_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Campagnes traitées par l'agent (liste complète). Une campagne n'a qu'un agent : l'ajouter ici la retire des autres agents."},"account_emails":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"description":"Boîtes d'envoi dont l'agent traite les réponses. Vide (défaut) : toutes."},"handle_followup":{"type":"boolean","description":"Relance automatiquement un lead qui ne répond plus (défaut false)."},"followup_after_days":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Jours sans réponse avant une relance (défaut 3)."},"max_followups":{"type":"integer","minimum":0,"maximum":10,"description":"Nombre maximum de relances, de 0 à 10 (défaut 2)."},"followup_business_days_only":{"type":"boolean","description":"Ne compter que les jours ouvrés pour les relances (défaut true)."},"respond_to_automatic_emails":{"type":"boolean","description":"Répondre aussi aux réponses automatiques, absences comprises (défaut true)."},"handle_objections":{"type":"boolean","description":"Traiter les objections au lieu de proposer d'en reparler (défaut true)."},"trigger_on_labels_enabled":{"type":"boolean","description":"Active le filtre sur le statut d'intérêt de la réponse (défaut false)."},"trigger_on_labels_mode":{"type":"string","enum":["include","exclude"],"description":"`include` : l'agent ne traite que les statuts de `trigger_on_labels`. `exclude` : il les ignore."},"trigger_on_labels":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt (valeurs standards ou labels personnalisés) utilisés par le filtre."},"monthly_credit_budget":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Nombre maximum de brouillons rédigés par mois civil. `null` (défaut) : illimité."},"no_show":{"type":"object","properties":{"enabled":{"type":"boolean"},"max_followups":{"type":"integer","minimum":0,"maximum":10}},"required":["enabled","max_followups"],"description":"Relance des prospects absents au rendez-vous : `enabled` et `max_followups` (0 à 10). Défaut : désactivé, 2 relances."},"tone":{"type":"string","enum":["friendly","neutral","matter_of_fact","professional","humorous"],"description":"Ton des réponses (défaut `professional`)."},"length":{"type":"string","enum":["concise","standard","thorough"],"description":"Longueur des réponses (défaut `concise`)."},"working_hours":{"anyOf":[{},{"type":"null"}],"description":"Plage horaire des envois automatiques, même forme qu'une entrée de `campaign_schedule.schedules` d'une campagne. `null` (défaut) : à toute heure."},"objective":{"type":"string","enum":["book_meeting","call_back","send_info","qualify","custom"],"description":"Objectif de la conversation (défaut `book_meeting`). Une fois atteint, l'agent arrête de relancer et passe la main."},"objective_details":{"type":"string","description":"Précisions sur l'objectif, indispensables avec `custom`."},"on_positive":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"],"description":"Règle pour une réponse positive : `action` `reply` (répondre, défaut), `review` (brouillon toujours à valider) ou `none` (ne pas répondre), et `instructions` propres à ce cas."},"on_negative":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"],"description":"Règle pour une réponse négative (défaut `none`). Même forme que `on_positive`."},"on_neutral":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"],"description":"Règle pour une réponse neutre (défaut `reply`). Même forme que `on_positive`."},"tool_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Outils HTTP ou MCP (`/ai-tools`) que l'agent peut appeler. Chaque id doit appartenir au workspace."},"skill_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Skills (`/ai-skills`) que l'agent peut charger. Chaque id doit appartenir au workspace."},"code_execution":{"type":"boolean","description":"Autorise l'outil d'exécution de code du modèle (défaut false)."},"integration_providers":{"type":"array","items":{"type":"string","enum":["google_calendar","airtable","hubspot","pipedrive","salesforce"]},"description":"Intégrations natives utilisables par l'agent (agenda, Airtable, CRM). Elles doivent être connectées dans `/integrations` pour servir."}},"required":["name"]},"AiAgentPatch":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Nom de l'agent."},"mode":{"type":"string","enum":["off","human_in_loop","autopilot"],"description":"`off` : classe les réponses sans rédiger. `human_in_loop` (défaut) : brouillons à valider. `autopilot` : envoi automatique après `reply_delay_minutes`, sauf cas qui exigent une validation."},"status":{"type":"integer","minimum":0,"maximum":1,"description":"1 actif (défaut), 0 inactif. Un agent inactif ne traite aucune réponse."},"instructions":{"type":"string","description":"Rôle et consignes générales de l'agent."},"knowledge":{"type":"string","description":"Connaissances mises à disposition : offre, prix, FAQ, réponses aux objections."},"booking_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Lien de prise de rendez-vous donné au prospect. Sans lien, l'agent propose des créneaux."},"signature":{"description":"Signature de l'agent (enregistrée telle quelle ; les réponses envoyées reçoivent la signature de la boîte d'envoi).","type":["string","null"]},"language":{"type":"string","description":"Langue des réponses : `auto` (défaut, langue du prospect) ou une langue explicite (`fr`, `en`...)."},"reply_delay_minutes":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Délai avant l'envoi automatique d'une réponse en autopilot, en minutes (défaut 15)."},"escalate_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt du lead pour lesquels le brouillon passe toujours en validation humaine (défaut `[-1, -2]`)."},"campaign_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Campagnes traitées par l'agent (liste complète). Une campagne n'a qu'un agent : l'ajouter ici la retire des autres agents."},"account_emails":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"description":"Boîtes d'envoi dont l'agent traite les réponses. Vide (défaut) : toutes."},"handle_followup":{"type":"boolean","description":"Relance automatiquement un lead qui ne répond plus (défaut false)."},"followup_after_days":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Jours sans réponse avant une relance (défaut 3)."},"max_followups":{"type":"integer","minimum":0,"maximum":10,"description":"Nombre maximum de relances, de 0 à 10 (défaut 2)."},"followup_business_days_only":{"type":"boolean","description":"Ne compter que les jours ouvrés pour les relances (défaut true)."},"respond_to_automatic_emails":{"type":"boolean","description":"Répondre aussi aux réponses automatiques, absences comprises (défaut true)."},"handle_objections":{"type":"boolean","description":"Traiter les objections au lieu de proposer d'en reparler (défaut true)."},"trigger_on_labels_enabled":{"type":"boolean","description":"Active le filtre sur le statut d'intérêt de la réponse (défaut false)."},"trigger_on_labels_mode":{"type":"string","enum":["include","exclude"],"description":"`include` : l'agent ne traite que les statuts de `trigger_on_labels`. `exclude` : il les ignore."},"trigger_on_labels":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt (valeurs standards ou labels personnalisés) utilisés par le filtre."},"monthly_credit_budget":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Nombre maximum de brouillons rédigés par mois civil. `null` (défaut) : illimité."},"no_show":{"type":"object","properties":{"enabled":{"type":"boolean"},"max_followups":{"type":"integer","minimum":0,"maximum":10}},"required":["enabled","max_followups"],"description":"Relance des prospects absents au rendez-vous : `enabled` et `max_followups` (0 à 10). Défaut : désactivé, 2 relances."},"tone":{"type":"string","enum":["friendly","neutral","matter_of_fact","professional","humorous"],"description":"Ton des réponses (défaut `professional`)."},"length":{"type":"string","enum":["concise","standard","thorough"],"description":"Longueur des réponses (défaut `concise`)."},"working_hours":{"anyOf":[{},{"type":"null"}],"description":"Plage horaire des envois automatiques, même forme qu'une entrée de `campaign_schedule.schedules` d'une campagne. `null` (défaut) : à toute heure."},"objective":{"type":"string","enum":["book_meeting","call_back","send_info","qualify","custom"],"description":"Objectif de la conversation (défaut `book_meeting`). Une fois atteint, l'agent arrête de relancer et passe la main."},"objective_details":{"type":"string","description":"Précisions sur l'objectif, indispensables avec `custom`."},"on_positive":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"],"description":"Règle pour une réponse positive : `action` `reply` (répondre, défaut), `review` (brouillon toujours à valider) ou `none` (ne pas répondre), et `instructions` propres à ce cas."},"on_negative":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"],"description":"Règle pour une réponse négative (défaut `none`). Même forme que `on_positive`."},"on_neutral":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action"],"description":"Règle pour une réponse neutre (défaut `reply`). Même forme que `on_positive`."},"tool_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Outils HTTP ou MCP (`/ai-tools`) que l'agent peut appeler. Chaque id doit appartenir au workspace."},"skill_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Skills (`/ai-skills`) que l'agent peut charger. Chaque id doit appartenir au workspace."},"code_execution":{"type":"boolean","description":"Autorise l'outil d'exécution de code du modèle (défaut false)."},"integration_providers":{"type":"array","items":{"type":"string","enum":["google_calendar","airtable","hubspot","pipedrive","salesforce"]},"description":"Intégrations natives utilisables par l'agent (agenda, Airtable, CRM). Elles doivent être connectées dans `/integrations` pour servir."}}},"AiToolCreate":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,40}$","description":"Nom technique unique dans le workspace : minuscules, chiffres et `_`, de 2 à 41 caractères, commençant par une lettre."},"label":{"type":"string","minLength":1,"description":"Nom affiché."},"description":{"default":"","description":"Ce que fait l'outil et quand l'utiliser : texte lu par l'agent pour décider de l'appeler.","type":"string"},"kind":{"type":"string","enum":["http","mcp"],"description":"`http` : appel d'une API. `mcp` : serveur MCP distant (Streamable HTTP), dont les outils se découvrent avec `POST /ai-tools/{id}/discover`."},"config":{"type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"body_template":{"type":["string","null"]}},"required":["url"],"description":"`url` (obligatoire, publique) ; pour `http` : `method` (défaut GET), `headers` et `body_template`. Les `{{param}}` de l'URL et du gabarit sont remplacés par les paramètres de l'appel ; en GET et DELETE, les autres paramètres passent en query string, sinon dans le corps JSON."},"auth":{"default":{"type":"none"},"description":"`none` (défaut), `bearer` (`Authorization: Bearer <secret>`) ou `header` (en-tête `header_name`, défaut `x-api-key`, qui reçoit le secret).","type":"object","properties":{"type":{"type":"string","enum":["none","bearer","header"]},"header_name":{"type":"string"}},"required":["type"]},"secret":{"description":"Jeton d'authentification, chiffré à l'enregistrement et jamais renvoyé. Absent ou vide : inchangé.","type":"string"},"input_schema":{"default":{"type":"object","properties":{}},"description":"JSON Schema (objet) des paramètres que l'agent doit fournir à un outil `http`.","type":"object","properties":{"type":{"default":"object","type":"string","const":"object"},"properties":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"required":{"type":"array","items":{"type":"string"}}},"additionalProperties":{}},"side_effect":{"default":false,"description":"true : l'outil est une action (écriture, envoi). L'agent la met en attente et elle ne s'exécute qu'à l'envoi de la réponse.","type":"boolean"},"mcp_tools":{"description":"Outils du serveur MCP (`mcp`) : ceux dont `enabled` vaut true sont proposés à l'agent ; `side_effect` les traite comme des actions.","type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"input_schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"enabled":{"type":"boolean"},"side_effect":{"type":"boolean"}},"required":["name","description","input_schema","enabled","side_effect"]}},"enabled":{"default":true,"description":"false : l'outil n'est proposé à aucun agent (défaut true).","type":"boolean"}},"required":["name","label","kind","config"]},"AiToolPatch":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,40}$","description":"Nom technique unique dans le workspace : minuscules, chiffres et `_`, de 2 à 41 caractères, commençant par une lettre."},"label":{"type":"string","minLength":1,"description":"Nom affiché."},"description":{"type":"string"},"kind":{"type":"string","enum":["http","mcp"],"description":"`http` : appel d'une API. `mcp` : serveur MCP distant (Streamable HTTP), dont les outils se découvrent avec `POST /ai-tools/{id}/discover`."},"config":{"description":"Fusionnée avec la configuration enregistrée : seuls les champs envoyés changent (`url` facultative, `body_template: null` efface le gabarit). `headers`, s'il est envoyé, remplace la liste des en-têtes.","type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"body_template":{"type":["string","null"]}}},"auth":{"type":"object","properties":{"type":{"type":"string","enum":["none","bearer","header"]},"header_name":{"type":"string"}},"required":["type"]},"secret":{"description":"Jeton d'authentification, chiffré à l'enregistrement et jamais renvoyé. Absent ou vide : inchangé.","type":"string"},"input_schema":{"type":"object","properties":{"type":{"default":"object","type":"string","const":"object"},"properties":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"required":{"type":"array","items":{"type":"string"}}},"additionalProperties":{}},"side_effect":{"type":"boolean"},"mcp_tools":{"description":"Outils du serveur MCP (`mcp`) : ceux dont `enabled` vaut true sont proposés à l'agent ; `side_effect` les traite comme des actions.","type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"input_schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"enabled":{"type":"boolean"},"side_effect":{"type":"boolean"}},"required":["name","description","input_schema","enabled","side_effect"]}},"enabled":{"type":"boolean"}}},"AiSkillCreate":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_-]{1,40}$","description":"Nom technique unique dans le workspace : minuscules, chiffres, `-` et `_`, de 2 à 41 caractères, commençant par une lettre."},"description":{"type":"string","minLength":1,"description":"Quand utiliser la skill : l'agent voit ce texte et décide de charger la skill."},"content":{"type":"string","minLength":1,"description":"Instructions détaillées (Markdown), chargées par l'agent à la demande."}},"required":["name","description","content"]},"AiSkillPatch":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_-]{1,40}$","description":"Nom technique unique dans le workspace : minuscules, chiffres, `-` et `_`, de 2 à 41 caractères, commençant par une lettre."},"description":{"type":"string","minLength":1,"description":"Quand utiliser la skill : l'agent voit ce texte et décide de charger la skill."},"content":{"type":"string","minLength":1,"description":"Instructions détaillées (Markdown), chargées par l'agent à la demande."}}},"WebhookCreate":{"type":"object","properties":{"name":{"type":["string","null"]},"target_hook_url":{"type":"string","format":"uri"},"campaign":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"event_type":{"anyOf":[{"type":"string","enum":["all_events","email_sent","email_opened","email_link_clicked","reply_received","auto_reply_received","email_bounced","lead_unsubscribed","campaign_completed","account_error","lead_neutral","lead_interested","lead_not_interested","lead_meeting_booked","lead_meeting_completed","lead_closed","lead_out_of_office","lead_wrong_person","lead_no_show","ai_draft_created","custom_label_any_positive","custom_label_any_negative"]},{"type":"null"}]},"custom_interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["target_hook_url"]},"WebhookPatch":{"type":"object","properties":{"name":{"type":["string","null"]},"target_hook_url":{"type":"string","format":"uri"},"campaign":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"event_type":{"anyOf":[{"type":"string","enum":["all_events","email_sent","email_opened","email_link_clicked","reply_received","auto_reply_received","email_bounced","lead_unsubscribed","campaign_completed","account_error","lead_neutral","lead_interested","lead_not_interested","lead_meeting_booked","lead_meeting_completed","lead_closed","lead_out_of_office","lead_wrong_person","lead_no_show","ai_draft_created","custom_label_any_positive","custom_label_any_negative"]},{"type":"null"}]},"custom_interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}}},"RestHookSubscribe":{"type":"object","properties":{"target_url":{"type":"string","format":"uri"},"hookUrl":{"type":"string","format":"uri"},"event":{"type":"string","enum":["all_events","email_sent","email_opened","email_link_clicked","reply_received","auto_reply_received","email_bounced","lead_unsubscribed","campaign_completed","account_error","lead_neutral","lead_interested","lead_not_interested","lead_meeting_booked","lead_meeting_completed","lead_closed","lead_out_of_office","lead_wrong_person","lead_no_show","ai_draft_created","custom_label_any_positive","custom_label_any_negative"]},"campaign":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"source":{"default":"rest_hook","type":"string","enum":["zapier","make","rest_hook"]}},"required":["event"]},"AirtableConnect":{"type":"object","properties":{"api_key":{"type":"string","minLength":20,"description":"Jeton d'accès personnel Airtable (`pat…`), vérifié auprès d'Airtable puis stocké chiffré. Jamais renvoyé."}},"required":["api_key"]},"AirtableSettingsPatch":{"type":"object","properties":{"settings":{"type":"object","properties":{"base_ids":{"type":"array","items":{"type":"string","pattern":"^app[A-Za-z0-9]+$"},"description":"Identifiants des bases autorisées (`app…`). Liste vide : aucune base."}},"required":["base_ids"]}},"required":["settings"]},"CrmTokenConnect":{"type":"object","properties":{"token":{"type":"string","minLength":10,"maxLength":500,"description":"HubSpot : jeton d'une application privée. Pipedrive : jeton d'API personnel. Vérifié auprès du CRM puis stocké chiffré, jamais renvoyé."}},"required":["token"]},"CrmSettingsPatch":{"type":"object","properties":{"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}}}},"required":["settings"]},"CrmTestSearch":{"type":"object","properties":{"query":{"default":"","description":"Texte recherché. S'il contient `@`, recherche exacte sur l'email ; sinon recherche libre (nom, email, société).","type":"string","maxLength":200}}},"GoogleCalendarSettingsPatch":{"type":"object","properties":{"settings":{"type":"object","properties":{"calendar_id":{"type":"string","minLength":1,"description":"Agenda où les rendez-vous sont créés (`primary` ou un identifiant de `GET /integrations/google-calendar/calendars`)."},"timezone":{"type":"string","description":"Fuseau IANA des horaires (ex. `Europe/Luxembourg`)."},"days":{"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6},"description":"Jours proposés, 0 = dimanche … 6 = samedi."},"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Début de la plage horaire (HH:MM)."},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Fin de la plage horaire (HH:MM), après `from`."},"duration_minutes":{"type":"integer","minimum":10,"maximum":240,"description":"Durée d'un rendez-vous."},"buffer_minutes":{"type":"integer","minimum":0,"maximum":120,"description":"Marge laissée libre avant et après chaque évènement existant."},"min_notice_hours":{"type":"number","minimum":0,"maximum":336,"description":"Délai minimum avant le premier créneau proposé."},"max_days_ahead":{"type":"integer","minimum":1,"maximum":60,"description":"Horizon maximum des créneaux proposés, en jours."},"add_meet":{"type":"boolean","description":"Ajouter un lien Google Meet au rendez-vous."},"title_template":{"type":"string","maxLength":200,"description":"Titre du rendez-vous, variables du lead acceptées (`{{companyName}}`…)."},"description_template":{"type":"string","maxLength":2000,"description":"Description du rendez-vous, variables du lead acceptées."},"check_calendars":{"type":"array","items":{"type":"string"},"description":"Agendas supplémentaires dont les évènements bloquent aussi des créneaux."}}}},"required":["settings"]},"GoogleCalendarCredentials":{"type":"object","properties":{"client_id":{"type":"string","pattern":"\\.apps\\.googleusercontent\\.com$","description":"ID client OAuth de l'application Google Cloud."},"client_secret":{"type":"string","minLength":10,"description":"Code secret du client, stocké chiffré et jamais renvoyé."}},"required":["client_id","client_secret"]},"Campaign":{"type":"object","properties":{"name":{"type":"string","minLength":1},"campaign_schedule":{"type":"object","properties":{"start_date":{"type":["string","null"]},"end_date":{"type":["string","null"]},"schedules":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"default":"Default","type":"string"},"timing":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$"},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}},"required":["from","to"],"additionalProperties":false},"days":{"type":"object","propertyNames":{"type":"string","enum":["0","1","2","3","4","5","6"]},"additionalProperties":{"type":"boolean"}},"timezone":{"type":"string"}},"required":["name","timing","days","timezone"],"additionalProperties":false}}},"required":["schedules"],"additionalProperties":false},"sequences":{"minItems":1,"type":"array","items":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"type":{"default":"email","type":"string","const":"email"},"delay":{"default":0,"type":"number","minimum":0,"maximum":527040},"delay_unit":{"default":"days","type":"string","enum":["minutes","hours","days"]},"pre_delay":{"type":"number","minimum":0},"pre_delay_unit":{"type":"string","enum":["minutes","hours","days"]},"variants":{"minItems":1,"maxItems":26,"type":"array","items":{"type":"object","properties":{"subject":{"default":"","type":"string"},"body":{"default":"","type":"string"},"v_disabled":{"type":"boolean"}},"required":["subject","body"],"additionalProperties":false}},"adv_con":{"type":"array","items":{"type":"object","properties":{"ac_trigger":{"type":"string","enum":["T_OE","T_RE"]},"ac_action":{"type":"string","enum":["A_SKIP_WAIT","A_CHANGE_WAIT"]},"ac_action_value":{"type":"number","minimum":0}},"required":["ac_trigger","ac_action"],"additionalProperties":false}}},"required":["type","delay","delay_unit","variants"],"additionalProperties":false}}},"required":["steps"],"additionalProperties":false}},"email_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"email_tag_list":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"daily_limit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"daily_max_leads":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"email_gap":{"type":"integer","minimum":0,"maximum":9007199254740991},"random_wait_max":{"type":"integer","minimum":0,"maximum":9007199254740991},"text_only":{"type":"boolean"},"first_email_text_only":{"type":"boolean"},"link_tracking":{"type":"boolean"},"open_tracking":{"type":"boolean"},"stop_on_reply":{"type":"boolean"},"stop_on_auto_reply":{"type":"boolean"},"stop_for_company":{"type":"boolean"},"prioritize_new_leads":{"type":"boolean"},"match_lead_esp":{"type":"boolean"},"allow_risky_contacts":{"type":"boolean"},"disable_bounce_protect":{"type":"boolean"},"insert_unsubscribe_header":{"type":"boolean"},"auto_variant_select":{"anyOf":[{"type":"object","properties":{"trigger":{"type":"string","enum":["reply_rate","click_rate","open_rate"]}},"required":["trigger"],"additionalProperties":false},{"type":"null"}]},"limit_emails_per_company_override":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["custom","disabled"]},"daily_limit":{"type":"integer","minimum":1,"maximum":9007199254740991},"scope":{"type":"string","enum":["per_campaign","across_workspace"]}},"required":["mode"],"additionalProperties":false},{"type":"null"}]},"provider_routing_rules":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string","enum":["send","do_not_send"]},"recipient_esp":{"type":"array","items":{"type":"string","enum":["all","google","outlook","other"]}},"sender_esp":{"type":"array","items":{"type":"string","enum":["all","google","outlook","other"]}}},"required":["action","recipient_esp","sender_esp"],"additionalProperties":false}},"cc_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"bcc_list":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"pl_value":{"type":["number","null"]},"ai_agent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la campagne."},"organization":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"0 brouillon, 1 active, 2 en pause, 3 terminée, 4 sous-séquences en cours, -1 boîtes en erreur, -2 pause automatique (taux de bounce), -99 compte suspendu."},"not_sending_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Raison pour laquelle une campagne active n'envoie pas (voir `GET /campaigns/{id}/sending-status`)."},"core_variables":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"custom_variables":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Variables de campagne, utilisables dans les emails comme `{{nom}}`."},"owned_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."},"timestamp_last_sent":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier email envoyé par la campagne."}},"required":["name","campaign_schedule","sequences","email_list","email_tag_list","daily_limit","daily_max_leads","email_gap","random_wait_max","text_only","first_email_text_only","link_tracking","open_tracking","stop_on_reply","stop_on_auto_reply","stop_for_company","prioritize_new_leads","match_lead_esp","allow_risky_contacts","disable_bounce_protect","insert_unsubscribe_header","auto_variant_select","limit_emails_per_company_override","provider_routing_rules","cc_list","bcc_list","pl_value","ai_agent_id","id","organization","status","not_sending_status","core_variables","custom_variables","owned_by","timestamp_created","timestamp_updated","timestamp_last_sent"],"additionalProperties":false},"Subsequence":{"type":"object","properties":{"parent_campaign":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","minLength":1},"conditions":{"type":"object","properties":{"crm_status":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"lead_activity":{"type":"array","items":{"anyOf":[{"type":"number","const":2},{"type":"number","const":4},{"type":"number","const":91}]}},"reply_contains":{"type":"string"}},"additionalProperties":false},"subsequence_schedule":{"anyOf":[{"type":"object","properties":{"start_date":{"type":["string","null"]},"end_date":{"type":["string","null"]},"schedules":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"default":"Default","type":"string"},"timing":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$"},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}},"required":["from","to"],"additionalProperties":false},"days":{"type":"object","propertyNames":{"type":"string","enum":["0","1","2","3","4","5","6"]},"additionalProperties":{"type":"boolean"}},"timezone":{"type":"string"}},"required":["name","timing","days","timezone"],"additionalProperties":false}}},"required":["schedules"],"additionalProperties":false},{"type":"null"}],"description":"Planning propre ; `null` = planning de la campagne parente."},"sequences":{"minItems":1,"type":"array","items":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"type":{"default":"email","type":"string","const":"email"},"delay":{"default":0,"type":"number","minimum":0,"maximum":527040},"delay_unit":{"default":"days","type":"string","enum":["minutes","hours","days"]},"pre_delay":{"type":"number","minimum":0},"pre_delay_unit":{"type":"string","enum":["minutes","hours","days"]},"variants":{"minItems":1,"maxItems":26,"type":"array","items":{"type":"object","properties":{"subject":{"default":"","type":"string"},"body":{"default":"","type":"string"},"v_disabled":{"type":"boolean"}},"required":["subject","body"],"additionalProperties":false}},"adv_con":{"type":"array","items":{"type":"object","properties":{"ac_trigger":{"type":"string","enum":["T_OE","T_RE"]},"ac_action":{"type":"string","enum":["A_SKIP_WAIT","A_CHANGE_WAIT"]},"ac_action_value":{"type":"number","minimum":0}},"required":["ac_trigger","ac_action"],"additionalProperties":false}}},"required":["type","delay","delay_unit","variants"],"additionalProperties":false}}},"required":["steps"],"additionalProperties":false}},"auto_variant_select":{"anyOf":[{"type":"object","properties":{"trigger":{"type":"string","enum":["reply_rate","click_rate","open_rate"]}},"required":["trigger"],"additionalProperties":false},{"type":"null"}]},"daily_limit_mode":{"type":"string","enum":["inherit","custom","unlimited"],"description":"`inherit` : limite de la campagne parente ; `custom` : `daily_limit` ; `unlimited` : sans limite propre."},"daily_limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"ignore_account_daily_limit":{"type":"boolean"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la sous-séquence."},"workspace":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 active, 2 en pause (mêmes codes que les campagnes)."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_leads_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière entrée d'un lead dans la sous-séquence."}},"required":["parent_campaign","name","conditions","subsequence_schedule","sequences","auto_variant_select","daily_limit_mode","daily_limit","ignore_account_daily_limit","id","workspace","status","timestamp_created","timestamp_leads_updated"],"additionalProperties":false},"LeadAiRun":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du traitement."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"campaign_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Campagne traitée."},"created_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Utilisateur qui a lancé le traitement (créateur de la clé API pour un appel par clé)."},"config":{"type":"object","properties":{"template":{"type":"string","enum":["company_name","first_name","salutation","icebreaker","custom"]},"prompt":{"type":"string","description":"Consigne effectivement utilisée (celle du modèle si aucune n'a été fournie)."},"target":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"field"},"name":{"type":"string","enum":["first_name","last_name","company_name","job_title","website","personalization"]}},"required":["kind","name"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"variable"},"name":{"type":"string","minLength":1,"maxLength":40}},"required":["kind","name"],"additionalProperties":false}]},"read_website":{"type":"boolean"}},"required":["template","prompt","target","read_website"],"additionalProperties":false},"mode":{"type":"string","enum":["sync","batch"],"description":"`sync` : appels directs par paquets de 20 leads ; `batch` : Message Batches API d'Anthropic (plus de 200 leads sans lecture de site), résultat en quelques minutes à quelques heures."},"status":{"type":"string","enum":["pending","running","done","cancelled","failed"]},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads de la campagne au lancement."},"processed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads traités."},"updated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads dont la valeur a changé."},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads en erreur (appel au modèle échoué ou réponse illisible)."},"cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Dernier lead traité (mode `sync`)."},"batch_id":{"description":"Identifiant du lot Anthropic (mode `batch`).","type":["string","null"]},"input_tokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"output_tokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"error":{"type":["string","null"]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de lancement."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière progression."},"timestamp_finished":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Fin du traitement (terminé, annulé ou en échec)."}},"required":["id","organization_id","campaign_id","created_by","config","mode","status","total","processed","updated","failed","cursor","batch_id","input_tokens","output_tokens","error","timestamp_created","timestamp_updated","timestamp_finished"],"additionalProperties":false},"LeadAiPreview":{"type":"object","properties":{"lead_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Lead testé."},"before":{"description":"Valeur actuelle du champ ou de la variable de destination.","type":["string","null"]},"value":{"type":"string","description":"Valeur proposée par le modèle (vide si l'information manque)."},"confident":{"type":"boolean","description":"`false` quand le modèle n'est pas sûr de sa réponse."},"error":{"description":"Présent quand l'appel au modèle a échoué pour ce lead.","type":"string"}},"required":["lead_id","before","value","confident"],"additionalProperties":false},"CampaignAnalyticsOverview":{"type":"object","properties":{"open_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"open_count_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"open_count_unique_by_step":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Leads uniques par index d'étape (`\"0\"` = première étape)."},"link_click_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"link_click_count_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"link_click_count_unique_by_step":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"reply_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reply_count_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reply_count_unique_by_step":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"reply_count_automatic":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reply_count_automatic_unique":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reply_count_automatic_unique_by_step":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"bounced_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unsubscribed_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"completed_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"emails_sent_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"contacted_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"new_leads_contacted_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total_opportunities":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à un statut d'intérêt positif sur la période."},"total_opportunity_value":{"type":"number","description":"`total_opportunities` × `pl_value`, calculé seulement quand une seule campagne est demandée (sinon 0)."},"total_interested":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à « Intéressé » (1)."},"total_meeting_booked":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à « RDV pris » (2)."},"total_meeting_completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à « RDV effectué » (3)."},"total_closed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads passés à « Gagné » (4)."}},"required":["open_count","open_count_unique","open_count_unique_by_step","link_click_count","link_click_count_unique","link_click_count_unique_by_step","reply_count","reply_count_unique","reply_count_unique_by_step","reply_count_automatic","reply_count_automatic_unique","reply_count_automatic_unique_by_step","bounced_count","unsubscribed_count","completed_count","emails_sent_count","contacted_count","new_leads_contacted_count","total_opportunities","total_opportunity_value","total_interested","total_meeting_booked","total_meeting_completed","total_closed"],"additionalProperties":false},"Lead":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"company_name":{"type":["string","null"]},"job_title":{"type":["string","null"]},"phone":{"type":["string","null"]},"website":{"type":["string","null"]},"personalization":{"type":["string","null"]},"lt_interest_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Statut d'intérêt. `null` = « Lead » (aucun statut). Statuts standards : 1 intéressé, 2 RDV pris, 3 RDV effectué, 4 gagné, 0 absent (out of office), -1 pas intéressé, -2 mauvais interlocuteur, -3 perdu, -4 absent au RDV. Labels personnalisés (`GET /lead-labels`) : 50 à 30000 positifs, -50 à -500 négatifs, -501 à -30000 neutres."},"pl_value_lead":{"type":["string","null"]},"assigned_to":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du lead. Une même adresse a une fiche (un id) par campagne ou liste où elle se trouve."},"organization":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"campaign":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Campagne du lead (null s'il est dans une liste)."},"list_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Liste du lead (null s'il est dans une campagne)."},"company_domain":{"description":"Domaine de l'adresse email, calculé.","type":["string","null"]},"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Variables personnalisées (`custom_variables` à l'écriture), plus `firstName`, `lastName` et `companyName` recopiés à la création. Utilisables dans les emails comme `{{nom}}`."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Statut dans la séquence : 1 actif (en séquence), 2 en pause, 3 terminé, -1 bounce, -2 désinscrit, -3 ignoré."},"verification_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Vérification de l'adresse : 0 non vérifiée, 1 valide, 11 et 12 en cours, -1 invalide, -2 risquée, -3 catch-all, -4 changement de poste."},"esp_code":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Fournisseur de la boîte du lead : 0 en attente, 1 Google, 2 Microsoft, 3 Zoho, 9 Yahoo, 999 autre, 1000 introuvable."},"email_open_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email_reply_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email_click_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email_opened_step":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"email_opened_variant":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"email_replied_step":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"email_replied_variant":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"email_clicked_step":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"email_clicked_variant":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"next_step":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Index (à partir de 0) de la prochaine étape de la séquence à envoyer."},"next_send_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Date prévue du prochain envoi (null : pas encore planifié, ou séquence arrêtée)."},"assigned_account":{"description":"Boîte d'envoi attitrée : le premier envoi fixe la boîte qui enverra les relances du fil.","type":["string","null"]},"thread_subject":{"description":"Objet du premier email, repris par les relances.","type":["string","null"]},"subsequence_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Sous-séquence en cours, sinon null."},"subsequence_next_step":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"timestamp_added_subsequence":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Entrée dans la sous-séquence en cours."},"last_step_from":{"type":["string","null"]},"last_step_id":{"type":["string","null"]},"last_step_timestamp_executed":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Exécution de la dernière étape."},"timestamp_last_contact":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier email envoyé au lead (null : jamais contacté)."},"timestamp_last_open":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernière ouverture."},"timestamp_last_reply":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernière réponse."},"timestamp_last_click":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier clic."},"timestamp_last_interest_change":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier changement du statut d'intérêt."},"timestamp_last_touch":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernière interaction."},"ai_objective_reached_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Date à laquelle l'agent IA a atteint son objectif avec ce lead."},"upload_method":{"type":"string","enum":["manual","api","website-visitor"],"description":"Origine : interface, API ou visiteur du site."},"uploaded_by_user":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date d'ajout."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."},"status_summary":{"type":"object","properties":{"lastStep":{"type":"object","properties":{"from":{"type":["string","null"]},"stepID":{"type":"string"},"timestamp_executed":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["from","stepID","timestamp_executed"],"additionalProperties":false}},"additionalProperties":false}},"required":["email","first_name","last_name","company_name","job_title","phone","website","personalization","lt_interest_status","pl_value_lead","assigned_to","id","organization","campaign","list_id","company_domain","payload","status","verification_status","esp_code","email_open_count","email_reply_count","email_click_count","email_opened_step","email_opened_variant","email_replied_step","email_replied_variant","email_clicked_step","email_clicked_variant","next_step","next_send_at","assigned_account","thread_subject","subsequence_id","subsequence_next_step","timestamp_added_subsequence","last_step_from","last_step_id","last_step_timestamp_executed","timestamp_last_contact","timestamp_last_open","timestamp_last_reply","timestamp_last_click","timestamp_last_interest_change","timestamp_last_touch","ai_objective_reached_at","upload_method","uploaded_by_user","timestamp_created","timestamp_updated","status_summary"],"additionalProperties":false},"LeadList":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Nom de la liste."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la liste."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"owned_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Utilisateur qui a créé la liste (créateur de la clé API pour un appel par clé)."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["name","id","organization_id","owned_by","timestamp_created"],"additionalProperties":false},"LeadLabel":{"type":"object","properties":{"label":{"type":"string","minLength":1},"interest_status_label":{"type":"string","enum":["positive","negative","neutral"]},"description":{"type":["string","null"]},"use_with_ai":{"type":"boolean"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du label."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"interest_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Code numérique du label, à utiliser comme `lt_interest_status` d'un lead : 50 à 30000 pour un label positif, -50 à -500 négatif, -501 à -30000 neutre."},"created_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["label","interest_status_label","description","use_with_ai","id","organization_id","interest_status","created_by","timestamp_created"],"additionalProperties":false},"BlocklistEntry":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'entrée."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"bl_value":{"type":"string","description":"Adresse email ou domaine bloqué, en minuscules."},"is_domain":{"type":"boolean","description":"true : tout le domaine est bloqué."},"reason":{"description":"Origine : null pour un ajout manuel, texte libre pour une désinscription automatique (lien de désinscription, demande dans une réponse).","type":["string","null"]},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date d'ajout."}},"required":["id","organization_id","bl_value","is_domain","reason","timestamp_created"],"additionalProperties":false},"CustomTag":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":60,"description":"Nom du tag (60 caractères au plus, unique dans le workspace)."},"description":{"type":["string","null"]},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du tag, à mettre dans `tags` d'une boîte d'envoi ou `email_tag_list` d'une campagne."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["label","description","id","organization_id","timestamp_created"],"additionalProperties":false},"Account":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"default":"","type":"string"},"last_name":{"default":"","type":"string"},"provider_code":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 SMTP/IMAP, 2 Google, 3 Microsoft."},"smtp_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"smtp_port":{"default":587,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_username":{"type":"string","minLength":1},"smtp_secure":{"type":"boolean","description":"true : TLS implicite (port 465) ; false : STARTTLS."},"imap_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"imap_port":{"default":993,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"imap_username":{"type":"string","minLength":1},"daily_limit":{"default":30,"type":"integer","minimum":1,"maximum":9007199254740991},"sending_gap":{"default":10,"type":"integer","minimum":0,"maximum":1440},"enable_slow_ramp":{"type":"boolean"},"signature":{"type":["string","null"]},"reply_to":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"tracking_domain_name":{"anyOf":[{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Tags de boîte (`custom-tags`) : une campagne peut cibler toutes les boîtes d'un tag."},"warmup":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Réglages de warmup enregistrés (le warmup n'est pas encore actif)."},"inbox_placement_test_limit":{"type":"integer","minimum":0,"maximum":9007199254740991},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la boîte."},"organization":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"auth_type":{"type":"string","enum":["password","oauth_google","oauth_microsoft"],"description":"`password` : SMTP/IMAP avec mot de passe. `oauth_google` / `oauth_microsoft` : boîte connectée par OAuth depuis l'interface, serveurs et identifiants gérés par le fournisseur."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 active, 2 en pause, 3 maintenance, -1 erreur de connexion, -2 erreur de soft bounce, -3 erreur d'envoi."},"status_message":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"Détail de la dernière erreur (`code`, `e_message`). `code: \"OAUTH_RECONNECT\"` : la boîte OAuth doit être reconnectée depuis l'interface."},"warmup_status":{"type":"number","const":0,"description":"Toujours 0 : pas de warmup dans Replexa (champ gardé pour la compatibilité des intégrations)."},"oauth_scopes":{"type":"array","items":{"type":"string"},"description":"Autorisations accordées par Google ou Microsoft (vide pour une boîte SMTP/IMAP)."},"oauth_connected_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Connexion OAuth de la boîte, null pour une boîte SMTP/IMAP."},"oauth_expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Expiration du jeton d'accès OAuth en cache (renouvelé automatiquement)."},"timestamp_last_imap_sync":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernière lecture IMAP des réponses."},"timestamp_last_sent":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier email envoyé par la boîte."},"added_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Utilisateur qui a ajouté la boîte (créateur de la clé API pour un ajout par l'API)."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date d'ajout."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."}},"required":["email","first_name","last_name","provider_code","smtp_host","smtp_port","smtp_username","smtp_secure","imap_host","imap_port","imap_username","daily_limit","sending_gap","tags","warmup","id","organization","auth_type","status","status_message","warmup_status","oauth_scopes","oauth_connected_at","oauth_expires_at","timestamp_last_imap_sync","timestamp_last_sent","added_by","timestamp_created","timestamp_updated"],"additionalProperties":false},"AccountDeleted":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"first_name":{"default":"","type":"string"},"last_name":{"default":"","type":"string"},"provider_code":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 SMTP/IMAP, 2 Google, 3 Microsoft."},"smtp_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"smtp_port":{"default":587,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"smtp_username":{"type":"string","minLength":1},"smtp_secure":{"type":"boolean","description":"true : TLS implicite (port 465) ; false : STARTTLS."},"imap_host":{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},"imap_port":{"default":993,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"imap_username":{"type":"string","minLength":1},"daily_limit":{"default":30,"type":"integer","minimum":1,"maximum":9007199254740991},"sending_gap":{"default":10,"type":"integer","minimum":0,"maximum":1440},"enable_slow_ramp":{"type":"boolean"},"signature":{"type":["string","null"]},"reply_to":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"tracking_domain_name":{"anyOf":[{"type":"string","maxLength":253,"pattern":"^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Tags de boîte (`custom-tags`) : une campagne peut cibler toutes les boîtes d'un tag."},"warmup":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Réglages de warmup enregistrés (le warmup n'est pas encore actif)."},"inbox_placement_test_limit":{"type":"integer","minimum":0,"maximum":9007199254740991},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la boîte."},"organization":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"auth_type":{"type":"string","enum":["password","oauth_google","oauth_microsoft"],"description":"`password` : SMTP/IMAP avec mot de passe. `oauth_google` / `oauth_microsoft` : boîte connectée par OAuth depuis l'interface, serveurs et identifiants gérés par le fournisseur."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 active, 2 en pause, 3 maintenance, -1 erreur de connexion, -2 erreur de soft bounce, -3 erreur d'envoi."},"status_message":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"Détail de la dernière erreur (`code`, `e_message`). `code: \"OAUTH_RECONNECT\"` : la boîte OAuth doit être reconnectée depuis l'interface."},"warmup_status":{"type":"number","const":0,"description":"Toujours 0 : pas de warmup dans Replexa (champ gardé pour la compatibilité des intégrations)."},"oauth_scopes":{"type":"array","items":{"type":"string"},"description":"Autorisations accordées par Google ou Microsoft (vide pour une boîte SMTP/IMAP)."},"oauth_connected_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Connexion OAuth de la boîte, null pour une boîte SMTP/IMAP."},"oauth_expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Expiration du jeton d'accès OAuth en cache (renouvelé automatiquement)."},"timestamp_last_imap_sync":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernière lecture IMAP des réponses."},"timestamp_last_sent":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernier email envoyé par la boîte."},"added_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Utilisateur qui a ajouté la boîte (créateur de la clé API pour un ajout par l'API)."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date d'ajout."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."},"oauth_revoked":{"description":"Boîte OAuth uniquement : true si Google a confirmé la révocation de l'accès. Toujours false pour Microsoft (jetons effacés, application à retirer sur myapps.microsoft.com).","type":"boolean"}},"required":["email","first_name","last_name","provider_code","smtp_host","smtp_port","smtp_username","smtp_secure","imap_host","imap_port","imap_username","daily_limit","sending_gap","tags","warmup","id","organization","auth_type","status","status_message","warmup_status","oauth_scopes","oauth_connected_at","oauth_expires_at","timestamp_last_imap_sync","timestamp_last_sent","added_by","timestamp_created","timestamp_updated"],"additionalProperties":false},"Email":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'email."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"message_id":{"type":"string","description":"En-tête Message-ID."},"in_reply_to":{"type":["string","null"]},"references_header":{"type":["string","null"]},"thread_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Fil de discussion : tous les emails d'un même échange partagent cette valeur."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Enregistrement dans Replexa."},"timestamp_email":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de l'email (envoi ou réception)."},"subject":{"type":"string"},"body":{"description":"Contenu. Absent de `GET /emails` avec `preview_only=true`.","type":"object","properties":{"html":{"type":"string"},"text":{"type":"string"}},"additionalProperties":false},"content_preview":{"description":"Début du texte, pour les listes.","type":["string","null"]},"from_address_email":{"type":["string","null"]},"from_address_json":{"anyOf":[{},{"type":"null"}],"description":"Expéditeur : `[{ name, address }]`."},"to_address_email_list":{"type":"string","description":"Destinataires séparés par des virgules."},"to_address_json":{"anyOf":[{},{"type":"null"}]},"cc_address_email_list":{"type":["string","null"]},"bcc_address_email_list":{"type":["string","null"]},"reply_to":{"type":["string","null"]},"eaccount":{"type":"string","description":"Boîte d'envoi du workspace qui a envoyé ou reçu l'email."},"campaign_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"subsequence_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"list_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"lead":{"description":"Email du lead concerné.","type":["string","null"]},"lead_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"step":{"description":"Étape de séquence `\"<séquence>_<étape>_<variante>\"`, ex. `\"0_2_0\"`.","type":["string","null"]},"step_index":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"variant_index":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"ue_type":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 envoyé par une campagne, 2 reçu, 3 envoyé à la main (réponse, transfert), 4 programmé ou brouillon IA."},"is_unread":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 non lu, 0 lu."},"is_auto_reply":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 si réponse automatique (absence, accusé de réception)."},"is_bounce":{"type":"boolean"},"is_focused":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 inbox prioritaire, 0 « autres »."},"i_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Statut d'intérêt attribué à l'email (null : non classé)."},"ai_interest_value":{"description":"Score de l'IA lors de la classification.","type":["number","null"]},"ai_assisted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 si rédigé par un agent IA."},"ai_agent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"ai_draft_status":{"anyOf":[{"type":"string","enum":["pending","approved","rejected","sending","sent"]},{"type":"null"}],"description":"Brouillon d'un agent IA : en attente de validation, approuvé, rejeté, en cours d'envoi, envoyé."},"send_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"1 envoyé, 2 programmé, -1 échec."},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Envoi programmé."},"marked_as_done":{"type":"boolean"},"reminder_ts":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Date de rappel."},"assigned_to":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Membre du workspace chargé de l'email."},"attachment_json":{"anyOf":[{},{"type":"null"}],"description":"Pièces jointes (métadonnées)."},"tracking_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Identifiant du pixel et des liens suivis."},"imap_uid":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","organization_id","message_id","in_reply_to","references_header","thread_id","timestamp_created","timestamp_email","subject","content_preview","from_address_email","from_address_json","to_address_email_list","to_address_json","cc_address_email_list","bcc_address_email_list","reply_to","eaccount","campaign_id","subsequence_id","list_id","lead","lead_id","step","step_index","variant_index","ue_type","is_unread","is_auto_reply","is_bounce","is_focused","i_status","ai_interest_value","ai_assisted","ai_agent_id","ai_draft_status","send_status","scheduled_at","marked_as_done","reminder_ts","assigned_to","attachment_json","tracking_id","imap_uid"],"additionalProperties":false},"AiAgent":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Nom de l'agent."},"mode":{"type":"string","enum":["off","human_in_loop","autopilot"],"description":"`off` : classe les réponses sans rédiger. `human_in_loop` (défaut) : brouillons à valider. `autopilot` : envoi automatique après `reply_delay_minutes`, sauf cas qui exigent une validation."},"status":{"type":"integer","minimum":0,"maximum":1,"description":"1 actif (défaut), 0 inactif. Un agent inactif ne traite aucune réponse."},"instructions":{"type":"string","description":"Rôle et consignes générales de l'agent."},"knowledge":{"type":"string","description":"Connaissances mises à disposition : offre, prix, FAQ, réponses aux objections."},"booking_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Lien de prise de rendez-vous donné au prospect. Sans lien, l'agent propose des créneaux."},"signature":{"description":"Signature de l'agent (enregistrée telle quelle ; les réponses envoyées reçoivent la signature de la boîte d'envoi).","type":["string","null"]},"language":{"type":"string","description":"Langue des réponses : `auto` (défaut, langue du prospect) ou une langue explicite (`fr`, `en`...)."},"reply_delay_minutes":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Délai avant l'envoi automatique d'une réponse en autopilot, en minutes (défaut 15)."},"escalate_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt du lead pour lesquels le brouillon passe toujours en validation humaine (défaut `[-1, -2]`)."},"campaign_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Campagnes traitées par l'agent (liste complète). Une campagne n'a qu'un agent : l'ajouter ici la retire des autres agents."},"account_emails":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"description":"Boîtes d'envoi dont l'agent traite les réponses. Vide (défaut) : toutes."},"handle_followup":{"type":"boolean","description":"Relance automatiquement un lead qui ne répond plus (défaut false)."},"followup_after_days":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Jours sans réponse avant une relance (défaut 3)."},"max_followups":{"type":"integer","minimum":0,"maximum":10,"description":"Nombre maximum de relances, de 0 à 10 (défaut 2)."},"followup_business_days_only":{"type":"boolean","description":"Ne compter que les jours ouvrés pour les relances (défaut true)."},"respond_to_automatic_emails":{"type":"boolean","description":"Répondre aussi aux réponses automatiques, absences comprises (défaut true)."},"handle_objections":{"type":"boolean","description":"Traiter les objections au lieu de proposer d'en reparler (défaut true)."},"trigger_on_labels_enabled":{"type":"boolean","description":"Active le filtre sur le statut d'intérêt de la réponse (défaut false)."},"trigger_on_labels_mode":{"type":"string","enum":["include","exclude"],"description":"`include` : l'agent ne traite que les statuts de `trigger_on_labels`. `exclude` : il les ignore."},"trigger_on_labels":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt (valeurs standards ou labels personnalisés) utilisés par le filtre."},"monthly_credit_budget":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Nombre maximum de brouillons rédigés par mois civil. `null` (défaut) : illimité."},"no_show":{"type":"object","properties":{"enabled":{"type":"boolean"},"max_followups":{"type":"integer","minimum":0,"maximum":10}},"required":["enabled","max_followups"],"additionalProperties":false,"description":"Relance des prospects absents au rendez-vous : `enabled` et `max_followups` (0 à 10). Défaut : désactivé, 2 relances."},"tone":{"type":"string","enum":["friendly","neutral","matter_of_fact","professional","humorous"],"description":"Ton des réponses (défaut `professional`)."},"length":{"type":"string","enum":["concise","standard","thorough"],"description":"Longueur des réponses (défaut `concise`)."},"working_hours":{"anyOf":[{},{"type":"null"}],"description":"Plage horaire des envois automatiques, même forme qu'une entrée de `campaign_schedule.schedules` d'une campagne. `null` (défaut) : à toute heure."},"objective":{"type":"string","enum":["book_meeting","call_back","send_info","qualify","custom"],"description":"Objectif de la conversation (défaut `book_meeting`). Une fois atteint, l'agent arrête de relancer et passe la main."},"objective_details":{"type":"string","description":"Précisions sur l'objectif, indispensables avec `custom`."},"on_positive":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action","instructions"],"additionalProperties":false,"description":"Règle pour une réponse positive : `action` `reply` (répondre, défaut), `review` (brouillon toujours à valider) ou `none` (ne pas répondre), et `instructions` propres à ce cas."},"on_negative":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action","instructions"],"additionalProperties":false,"description":"Règle pour une réponse négative (défaut `none`). Même forme que `on_positive`."},"on_neutral":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action","instructions"],"additionalProperties":false,"description":"Règle pour une réponse neutre (défaut `reply`). Même forme que `on_positive`."},"tool_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Outils HTTP ou MCP (`/ai-tools`) que l'agent peut appeler. Chaque id doit appartenir au workspace."},"skill_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Skills (`/ai-skills`) que l'agent peut charger. Chaque id doit appartenir au workspace."},"code_execution":{"type":"boolean","description":"Autorise l'outil d'exécution de code du modèle (défaut false)."},"integration_providers":{"type":"array","items":{"type":"string","enum":["google_calendar","airtable","hubspot","pipedrive","salesforce"]},"description":"Intégrations natives utilisables par l'agent (agenda, Airtable, CRM). Elles doivent être connectées dans `/integrations` pour servir."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'agent."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."}},"required":["name","mode","status","instructions","knowledge","booking_url","signature","language","reply_delay_minutes","escalate_statuses","campaign_ids","account_emails","handle_followup","followup_after_days","max_followups","followup_business_days_only","respond_to_automatic_emails","handle_objections","trigger_on_labels_enabled","trigger_on_labels_mode","trigger_on_labels","monthly_credit_budget","no_show","tone","length","working_hours","objective","objective_details","on_positive","on_negative","on_neutral","tool_ids","skill_ids","code_execution","integration_providers","id","organization_id","timestamp_created","timestamp_updated"],"additionalProperties":false},"AiAgentDetail":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Nom de l'agent."},"mode":{"type":"string","enum":["off","human_in_loop","autopilot"],"description":"`off` : classe les réponses sans rédiger. `human_in_loop` (défaut) : brouillons à valider. `autopilot` : envoi automatique après `reply_delay_minutes`, sauf cas qui exigent une validation."},"status":{"type":"integer","minimum":0,"maximum":1,"description":"1 actif (défaut), 0 inactif. Un agent inactif ne traite aucune réponse."},"instructions":{"type":"string","description":"Rôle et consignes générales de l'agent."},"knowledge":{"type":"string","description":"Connaissances mises à disposition : offre, prix, FAQ, réponses aux objections."},"booking_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Lien de prise de rendez-vous donné au prospect. Sans lien, l'agent propose des créneaux."},"signature":{"description":"Signature de l'agent (enregistrée telle quelle ; les réponses envoyées reçoivent la signature de la boîte d'envoi).","type":["string","null"]},"language":{"type":"string","description":"Langue des réponses : `auto` (défaut, langue du prospect) ou une langue explicite (`fr`, `en`...)."},"reply_delay_minutes":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Délai avant l'envoi automatique d'une réponse en autopilot, en minutes (défaut 15)."},"escalate_statuses":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt du lead pour lesquels le brouillon passe toujours en validation humaine (défaut `[-1, -2]`)."},"campaign_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Campagnes traitées par l'agent (liste complète). Une campagne n'a qu'un agent : l'ajouter ici la retire des autres agents."},"account_emails":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"description":"Boîtes d'envoi dont l'agent traite les réponses. Vide (défaut) : toutes."},"handle_followup":{"type":"boolean","description":"Relance automatiquement un lead qui ne répond plus (défaut false)."},"followup_after_days":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Jours sans réponse avant une relance (défaut 3)."},"max_followups":{"type":"integer","minimum":0,"maximum":10,"description":"Nombre maximum de relances, de 0 à 10 (défaut 2)."},"followup_business_days_only":{"type":"boolean","description":"Ne compter que les jours ouvrés pour les relances (défaut true)."},"respond_to_automatic_emails":{"type":"boolean","description":"Répondre aussi aux réponses automatiques, absences comprises (défaut true)."},"handle_objections":{"type":"boolean","description":"Traiter les objections au lieu de proposer d'en reparler (défaut true)."},"trigger_on_labels_enabled":{"type":"boolean","description":"Active le filtre sur le statut d'intérêt de la réponse (défaut false)."},"trigger_on_labels_mode":{"type":"string","enum":["include","exclude"],"description":"`include` : l'agent ne traite que les statuts de `trigger_on_labels`. `exclude` : il les ignore."},"trigger_on_labels":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Statuts d'intérêt (valeurs standards ou labels personnalisés) utilisés par le filtre."},"monthly_credit_budget":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Nombre maximum de brouillons rédigés par mois civil. `null` (défaut) : illimité."},"no_show":{"type":"object","properties":{"enabled":{"type":"boolean"},"max_followups":{"type":"integer","minimum":0,"maximum":10}},"required":["enabled","max_followups"],"additionalProperties":false,"description":"Relance des prospects absents au rendez-vous : `enabled` et `max_followups` (0 à 10). Défaut : désactivé, 2 relances."},"tone":{"type":"string","enum":["friendly","neutral","matter_of_fact","professional","humorous"],"description":"Ton des réponses (défaut `professional`)."},"length":{"type":"string","enum":["concise","standard","thorough"],"description":"Longueur des réponses (défaut `concise`)."},"working_hours":{"anyOf":[{},{"type":"null"}],"description":"Plage horaire des envois automatiques, même forme qu'une entrée de `campaign_schedule.schedules` d'une campagne. `null` (défaut) : à toute heure."},"objective":{"type":"string","enum":["book_meeting","call_back","send_info","qualify","custom"],"description":"Objectif de la conversation (défaut `book_meeting`). Une fois atteint, l'agent arrête de relancer et passe la main."},"objective_details":{"type":"string","description":"Précisions sur l'objectif, indispensables avec `custom`."},"on_positive":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action","instructions"],"additionalProperties":false,"description":"Règle pour une réponse positive : `action` `reply` (répondre, défaut), `review` (brouillon toujours à valider) ou `none` (ne pas répondre), et `instructions` propres à ce cas."},"on_negative":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action","instructions"],"additionalProperties":false,"description":"Règle pour une réponse négative (défaut `none`). Même forme que `on_positive`."},"on_neutral":{"type":"object","properties":{"action":{"type":"string","enum":["reply","review","none"]},"instructions":{"default":"","type":"string"}},"required":["action","instructions"],"additionalProperties":false,"description":"Règle pour une réponse neutre (défaut `reply`). Même forme que `on_positive`."},"tool_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Outils HTTP ou MCP (`/ai-tools`) que l'agent peut appeler. Chaque id doit appartenir au workspace."},"skill_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Skills (`/ai-skills`) que l'agent peut charger. Chaque id doit appartenir au workspace."},"code_execution":{"type":"boolean","description":"Autorise l'outil d'exécution de code du modèle (défaut false)."},"integration_providers":{"type":"array","items":{"type":"string","enum":["google_calendar","airtable","hubspot","pipedrive","salesforce"]},"description":"Intégrations natives utilisables par l'agent (agenda, Airtable, CRM). Elles doivent être connectées dans `/integrations` pour servir."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'agent."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."},"guidance":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la consigne."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"agent_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Agent auquel la consigne s'applique."},"category":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"0 bases, 1 style de communication, 2 précisions de contexte, 3 passage de relais et escalade, 4 autre."},"label":{"type":"string"},"instruction":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 active, 0 désactivée (ignorée par l'agent)."},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Ordre dans la catégorie."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["id","organization_id","agent_id","category","label","instruction","status","position","timestamp_created"],"additionalProperties":false},"description":"Toutes les consignes de l'agent, désactivées comprises, triées par catégorie puis position."},"stats":{"type":"object","properties":{"handled":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Entrées du journal d'activité de l'agent."},"pending":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Brouillons en attente de validation (`action_pending`)."},"sent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Réponses envoyées."},"positive":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Réponses classées positives."},"negative":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Réponses classées négatives."},"objectives_reached":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Leads des campagnes de l'agent dont l'objectif est atteint."}},"required":["handled","pending","sent","positive","negative","objectives_reached"],"additionalProperties":false,"description":"Chiffres clés de l'agent, tous temps confondus."}},"required":["name","mode","status","instructions","knowledge","booking_url","signature","language","reply_delay_minutes","escalate_statuses","campaign_ids","account_emails","handle_followup","followup_after_days","max_followups","followup_business_days_only","respond_to_automatic_emails","handle_objections","trigger_on_labels_enabled","trigger_on_labels_mode","trigger_on_labels","monthly_credit_budget","no_show","tone","length","working_hours","objective","objective_details","on_positive","on_negative","on_neutral","tool_ids","skill_ids","code_execution","integration_providers","id","organization_id","timestamp_created","timestamp_updated","guidance","stats"],"additionalProperties":false},"AiAgentGuidance":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la consigne."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"agent_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Agent auquel la consigne s'applique."},"category":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"0 bases, 1 style de communication, 2 précisions de contexte, 3 passage de relais et escalade, 4 autre."},"label":{"type":"string"},"instruction":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 active, 0 désactivée (ignorée par l'agent)."},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Ordre dans la catégorie."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["id","organization_id","agent_id","category","label","instruction","status","position","timestamp_created"],"additionalProperties":false},"AiAgentActivity":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'entrée du journal (curseur de pagination)."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"agent_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Agent concerné."},"lead_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"thread_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Fil de discussion dans l'inbox."},"source_email_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Réponse du prospect qui a déclenché l'agent."},"draft_email_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Brouillon rédigé par l'agent, s'il y en a un."},"job_type":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 réponse à un email reçu, 2 relance d'un lead silencieux, 3 relance après un rendez-vous manqué."},"sending_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"1 envoyé, 2 programmé, -1 échec d'envoi, `null` rien à envoyer (ou brouillon rejeté)."},"requires_hitl":{"type":"boolean","description":"Le brouillon exige une validation humaine."},"action_pending":{"type":"boolean","description":"En attente de validation ou de rejet (file de validation)."},"information_requested":{"description":"Information qui manque à l'agent pour bien répondre.","type":["string","null"]},"reasoning":{"description":"Raisonnement de l'agent, ou raison de l'absence de réponse.","type":["string","null"]},"error_code":{"description":"`plan_credits_exhausted` (crédits IA du plan épuisés), `budget_exhausted` (budget mensuel de l'agent atteint), `send_failed` (envoi automatique en échec).","type":["string","null"]},"tokens_used":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"polarity":{"anyOf":[{"type":"string","enum":["positive","negative","neutral"]},{"type":"null"}],"description":"Polarité de la réponse du prospect."},"objective_reached":{"type":"boolean","description":"L'agent estime l'objectif atteint avec cette réponse."},"tool_calls":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Outil appelé."},"input":{"description":"Paramètres de l'appel."},"output":{"type":"string","description":"Résultat (tronqué) ou message d'erreur."},"deferred":{"type":"boolean","description":"true : action mise en attente jusqu'à l'envoi de la réponse."},"error":{"type":"boolean"},"at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Heure de l'appel."}},"required":["name","input","output","deferred","error","at"],"additionalProperties":false},"description":"Appels d'outils faits pendant la rédaction, puis actions exécutées à l'envoi."},"pending_actions":{"type":"array","items":{"type":"object","properties":{"tool_id":{"type":"string","description":"Outil `/ai-tools`, ou `builtin:...` pour une intégration native (agenda, Airtable, CRM)."},"mcp_tool":{"description":"Outil du serveur MCP, pour un outil `mcp`.","type":["string","null"]},"name":{"type":"string"},"label":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Paramètres choisis par l'agent."},"lead_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["tool_id","mcp_tool","name","label","input"],"additionalProperties":false},"description":"Actions qui s'exécuteront à la validation du brouillon."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de l'entrée."},"draft":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"subject":{"type":"string"},"body":{"type":"object","properties":{"text":{"type":"string"},"html":{"type":"string"}},"additionalProperties":false},"eaccount":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Boîte qui enverra la réponse."},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Envoi automatique prévu (autopilot)."},"ai_draft_status":{"anyOf":[{"type":"string","enum":["pending","approved","rejected","sending","sent"]},{"type":"null"}],"description":"`pending` à valider, `approved` programmé, `rejected` rejeté, `sending` en cours d'envoi, `sent` envoyé."}},"required":["id","subject","body","eaccount","scheduled_at","ai_draft_status"],"additionalProperties":false},{"type":"null"}],"description":"Brouillon (`draft_email_id`), ou `null`."},"source":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"subject":{"type":"string"},"content_preview":{"type":["string","null"]},"from_address_email":{"type":["string","null"]},"thread_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"i_status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Statut d'intérêt attribué à la réponse."}},"required":["id","subject","content_preview","from_address_email","thread_id","i_status"],"additionalProperties":false},{"type":"null"}],"description":"Réponse du prospect (`source_email_id`), ou `null`."}},"required":["id","organization_id","agent_id","lead_id","thread_id","source_email_id","draft_email_id","job_type","sending_status","requires_hitl","action_pending","information_requested","reasoning","error_code","tokens_used","polarity","objective_reached","tool_calls","pending_actions","timestamp_created","draft","source"],"additionalProperties":false},"AiAgentSentReply":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'email : celui du brouillon, désormais envoyé."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"message_id":{"type":"string"},"thread_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"subject":{"type":"string"},"body":{"type":"object","properties":{"text":{"type":"string"},"html":{"type":"string"}},"required":["text","html"],"additionalProperties":false},"content_preview":{"type":["string","null"]},"from_address_email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"to_address_email_list":{"type":"string","description":"Destinataires, séparés par des virgules."},"eaccount":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Boîte qui a envoyé la réponse."},"campaign_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"lead_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"ue_type":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"3 : email envoyé depuis l'inbox."},"ai_assisted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 : rédigé par un agent IA."},"ai_agent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"ai_draft_status":{"type":"string","const":"sent"},"send_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 envoyé."},"timestamp_email":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Heure d'envoi."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Création du brouillon."},"actions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Outil appelé."},"input":{"description":"Paramètres de l'appel."},"output":{"type":"string","description":"Résultat (tronqué) ou message d'erreur."},"deferred":{"type":"boolean","description":"true : action mise en attente jusqu'à l'envoi de la réponse."},"error":{"type":"boolean"},"at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Heure de l'appel."}},"required":["name","input","output","deferred","error","at"],"additionalProperties":false},"description":"Actions en attente exécutées après l'envoi (vide si `run_actions` vaut false). Un échec est signalé par `error: true` sans annuler l'envoi."}},"required":["id","organization_id","message_id","thread_id","subject","body","content_preview","from_address_email","to_address_email_list","eaccount","campaign_id","lead_id","ue_type","ai_assisted","ai_agent_id","ai_draft_status","send_status","timestamp_email","timestamp_created","actions"],"additionalProperties":{},"description":"Email envoyé (ligne complète de l'inbox) et résultat des actions."},"AiAgentSimulation":{"type":"object","properties":{"classification":{"type":"object","properties":{"interest_value":{"description":"Statut d'intérêt détecté (1 intéressé, 2 RDV pris, 0 absent, -1 pas intéressé, -2 mauvaise personne, ou valeur d'un label personnalisé).","type":["number","null"]},"label_key":{"type":"string"},"confidence":{"type":"number"},"is_auto_reply":{"type":"boolean"},"unsubscribe_request":{"type":"boolean"},"referral_email":{"description":"Contact vers lequel le prospect redirige.","type":["string","null"]},"return_date":{"description":"Date de retour d'un absent.","type":["string","null"]},"reason":{"type":"string"}},"required":["interest_value","label_key","confidence","is_auto_reply","unsubscribe_request","referral_email","return_date","reason"],"additionalProperties":false},"polarity":{"type":"string","enum":["positive","negative","neutral"]},"policy_action":{"type":"string","enum":["reply","review","none"],"description":"Règle `on_<polarité>` qui s'applique."},"outcome":{"type":"string","enum":["no_reply","review","autopilot"],"description":"Ce que l'agent ferait : pas de réponse, brouillon à valider, ou envoi automatique."},"outcome_reason":{"type":"string"},"draft":{"anyOf":[{"type":"object","properties":{"action":{"type":"string","enum":["reply","escalate","no_reply"]},"body_text":{"type":"string"},"information_requested":{"type":["string","null"]},"suggested_interest":{"type":["string","null"]},"objective_reached":{"type":"boolean"},"reasoning":{"type":"string"}},"required":["action","body_text","information_requested","suggested_interest","objective_reached","reasoning"],"additionalProperties":false},{"type":"null"}],"description":"Brouillon rédigé, ou `null` quand l'agent ne rédigerait rien."},"tool_calls":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Outil appelé."},"input":{"description":"Paramètres de l'appel."},"output":{"type":"string","description":"Résultat (tronqué) ou message d'erreur."},"deferred":{"type":"boolean","description":"true : action mise en attente jusqu'à l'envoi de la réponse."},"error":{"type":"boolean"},"at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Heure de l'appel."}},"required":["name","input","output","deferred","error","at"],"additionalProperties":false}},"deferred_actions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["name","label","input"],"additionalProperties":false},"description":"Actions que l'envoi déclencherait, jamais exécutées ici."},"dry_run":{"type":"boolean","const":true}},"required":["classification","polarity","policy_action","outcome","outcome_reason","draft","tool_calls","deferred_actions","dry_run"],"additionalProperties":false},"AiTool":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,40}$","description":"Nom technique unique dans le workspace : minuscules, chiffres et `_`, de 2 à 41 caractères, commençant par une lettre."},"label":{"type":"string","minLength":1,"description":"Nom affiché."},"description":{"default":"","description":"Ce que fait l'outil et quand l'utiliser : texte lu par l'agent pour décider de l'appeler.","type":"string"},"kind":{"type":"string","enum":["http","mcp"],"description":"`http` : appel d'une API. `mcp` : serveur MCP distant (Streamable HTTP), dont les outils se découvrent avec `POST /ai-tools/{id}/discover`."},"config":{"type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"En-têtes envoyés à chaque appel. Les valeurs ne sont visibles que d'un admin ou owner ; pour les autres rôles, chaque valeur est remplacée par `••••••`."},"body_template":{"type":["string","null"]}},"required":["url","headers"],"additionalProperties":false,"description":"Adresse et réglages d'appel."},"auth":{"default":{"type":"none"},"description":"`none` (défaut), `bearer` (`Authorization: Bearer <secret>`) ou `header` (en-tête `header_name`, défaut `x-api-key`, qui reçoit le secret).","type":"object","properties":{"type":{"type":"string","enum":["none","bearer","header"]},"header_name":{"type":"string"}},"required":["type"],"additionalProperties":false},"input_schema":{"default":{"type":"object","properties":{}},"description":"JSON Schema (objet) des paramètres que l'agent doit fournir à un outil `http`.","type":"object","properties":{"type":{"default":"object","type":"string","const":"object"},"properties":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"required":{"type":"array","items":{"type":"string"}}},"required":["type","properties"],"additionalProperties":{}},"side_effect":{"default":false,"description":"true : l'outil est une action (écriture, envoi). L'agent la met en attente et elle ne s'exécute qu'à l'envoi de la réponse.","type":"boolean"},"mcp_tools":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"input_schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"enabled":{"type":"boolean"},"side_effect":{"type":"boolean"}},"required":["name","description","input_schema","enabled","side_effect"],"additionalProperties":false},"description":"Outils découverts sur le serveur MCP (vide pour un outil `http`)."},"enabled":{"default":true,"description":"false : l'outil n'est proposé à aucun agent (défaut true).","type":"boolean"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'outil."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"has_secret":{"type":"boolean","description":"Un jeton est enregistré. Le jeton lui-même n'est jamais renvoyé, quel que soit le rôle."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."}},"required":["name","label","description","kind","config","auth","input_schema","side_effect","mcp_tools","enabled","id","organization_id","has_secret","timestamp_created","timestamp_updated"],"additionalProperties":false},"AiSkill":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_-]{1,40}$","description":"Nom technique unique dans le workspace : minuscules, chiffres, `-` et `_`, de 2 à 41 caractères, commençant par une lettre."},"description":{"type":"string","minLength":1,"description":"Quand utiliser la skill : l'agent voit ce texte et décide de charger la skill."},"content":{"type":"string","minLength":1,"description":"Instructions détaillées (Markdown), chargées par l'agent à la demande."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la skill."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."}},"required":["name","description","content","id","organization_id","timestamp_created","timestamp_updated"],"additionalProperties":false},"Webhook":{"type":"object","properties":{"name":{"type":["string","null"]},"target_hook_url":{"type":"string","format":"uri"},"campaign":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"event_type":{"anyOf":[{"type":"string","enum":["all_events","email_sent","email_opened","email_link_clicked","reply_received","auto_reply_received","email_bounced","lead_unsubscribed","campaign_completed","account_error","lead_neutral","lead_interested","lead_not_interested","lead_meeting_booked","lead_meeting_completed","lead_closed","lead_out_of_office","lead_wrong_person","lead_no_show","ai_draft_created","custom_label_any_positive","custom_label_any_negative"]},{"type":"null"}]},"custom_interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du webhook."},"organization":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 actif, -1 en erreur (désactivé après trop d'échecs, voir `POST /webhooks/{id}/resume`)."},"source":{"type":"string","enum":["manual","zapier","make","rest_hook"],"description":"Origine : `manual` (API ou interface), ou abonnement REST Hooks créé par `POST /hooks/subscribe`."},"timestamp_error":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Date de passage en erreur, `null` si actif."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["name","target_hook_url","campaign","event_type","custom_interest_value","headers","id","organization","status","source","timestamp_error","timestamp_created"],"additionalProperties":false},"WebhookWithSecret":{"type":"object","properties":{"name":{"type":["string","null"]},"target_hook_url":{"type":"string","format":"uri"},"campaign":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"event_type":{"anyOf":[{"type":"string","enum":["all_events","email_sent","email_opened","email_link_clicked","reply_received","auto_reply_received","email_bounced","lead_unsubscribed","campaign_completed","account_error","lead_neutral","lead_interested","lead_not_interested","lead_meeting_booked","lead_meeting_completed","lead_closed","lead_out_of_office","lead_wrong_person","lead_no_show","ai_draft_created","custom_label_any_positive","custom_label_any_negative"]},{"type":"null"}]},"custom_interest_value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du webhook."},"organization":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 actif, -1 en erreur (désactivé après trop d'échecs, voir `POST /webhooks/{id}/resume`)."},"source":{"type":"string","enum":["manual","zapier","make","rest_hook"],"description":"Origine : `manual` (API ou interface), ou abonnement REST Hooks créé par `POST /hooks/subscribe`."},"timestamp_error":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Date de passage en erreur, `null` si actif."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"signing_secret":{"type":"string","description":"Secret de signature HMAC (48 caractères hexadécimaux). Renvoyé uniquement à la création."}},"required":["name","target_hook_url","campaign","event_type","custom_interest_value","headers","id","organization","status","source","timestamp_error","timestamp_created","signing_secret"],"additionalProperties":false},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la livraison."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace propriétaire."},"webhook_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook destinataire."},"webhook_url":{"type":"string","format":"uri","description":"URL visée au moment où l'évènement a été mis en file."},"event_type":{"type":"string","description":"Type d'évènement du payload (`reply_received`, `custom_label`…)."},"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Corps JSON envoyé (voir le modèle `WebhookPayload`)."},"lead_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"success":{"type":"boolean","description":"`true` dès qu'une tentative a reçu une réponse 2xx."},"status_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Code HTTP de la dernière tentative, `null` sans réponse (délai dépassé, erreur réseau, adresse refusée) ou avant la première tentative."},"error_message":{"description":"Erreur de la dernière tentative (code et début de la réponse, ou message réseau).","type":["string","null"]},"response_time_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"retry_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Tentatives échouées jusqu'ici (0 à 6)."},"will_retry":{"type":"boolean","description":"Une tentative est prévue. `false` après un succès, quand les tentatives sont épuisées ou quand le webhook est désactivé."},"timestamp_next_retry":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de la prochaine tentative (significative seulement si `will_retry`)."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de mise en file de l'évènement."}},"required":["id","organization_id","webhook_id","webhook_url","event_type","payload","lead_email","success","status_code","error_message","response_time_ms","retry_count","will_retry","timestamp_next_retry","timestamp_created"],"additionalProperties":false},"WebhookPayload":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de l'évènement."},"event_type":{"type":"string","description":"Type d'évènement (`GET /webhooks/event-types`), ou `custom_label` pour un label personnalisé."},"workspace":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace concerné."},"campaign_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"campaign_name":{"type":["string","null"]},"is_first":{"type":"boolean","description":"Premier évènement de ce type pour ce lead."},"lead_email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"email_account":{"description":"Boîte d'envoi concernée.","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"step":{"description":"Étape de la séquence, à partir de 1.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"variant":{"description":"Variante de l'étape, à partir de 1.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"custom_interest_value":{"description":"Valeur du label personnalisé (évènement `custom_label`).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email_subject":{"description":"Email envoyé : objet (`email_text` et `email_html` pour le corps).","type":"string"},"reply_subject":{"description":"Réponse reçue : objet (`reply_text`, `reply_html`, `reply_text_snippet` et `unibox_url` l'accompagnent).","type":"string"},"reply_text":{"type":"string"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"companyName":{"type":["string","null"]},"website":{"type":["string","null"]},"phone":{"type":["string","null"]},"personalization":{"type":["string","null"]}},"required":["timestamp","event_type","workspace","campaign_id","campaign_name","is_first"],"additionalProperties":{},"description":"Corps JSON d'une livraison. Les champs présents dépendent de l'évènement. Les variables personnalisées du lead sont ajoutées à plat, ainsi que les données propres à l'évènement (`interest_value`, `interest_label` et `polarity` pour un changement de statut d'intérêt)."},"AirtableIntegration":{"type":"object","properties":{"configured":{"type":"boolean","description":"Des identifiants sont enregistrés."},"connected":{"type":"boolean","description":"L'intégration est utilisable (statut `connected` et jeton présent)."},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"account_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}],"description":"Compte connecté côté service."},"last_error":{"type":["string","null"]},"public_config":{"type":"object","properties":{"user_id":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"token_hint":{"type":"string","description":"4 derniers caractères du jeton, précédés de `…`."}},"additionalProperties":false,"description":"Partie non secrète de la configuration. Le jeton lui-même n'est jamais renvoyé."},"settings":{"anyOf":[{"type":"object","properties":{"base_ids":{"type":"array","items":{"type":"string","pattern":"^app[A-Za-z0-9]+$"},"description":"Identifiants des bases autorisées (`app…`). Liste vide : aucune base."}},"required":["base_ids"],"additionalProperties":false},{"type":"null"}],"description":"Bases autorisées pour les agents IA, `null` si Airtable n'a jamais été connecté."}},"required":["configured","connected","status","account_email","last_error","public_config","settings"],"additionalProperties":false},"GoogleCalendarIntegration":{"type":"object","properties":{"configured":{"type":"boolean","description":"Une application Google (ID client et secret) est disponible, celle du workspace ou celle de l'instance."},"connected":{"type":"boolean","description":"L'intégration est utilisable (statut `connected` et jeton présent)."},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"account_email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}],"description":"Compte connecté côté service."},"last_error":{"type":["string","null"]},"public_config":{"type":"object","properties":{"client_id":{"type":"string"}},"additionalProperties":false,"description":"ID client enregistré. Le secret et les jetons OAuth ne sont jamais renvoyés."},"settings":{"anyOf":[{"type":"object","properties":{"calendar_id":{"type":"string","minLength":1,"description":"Agenda où les rendez-vous sont créés (`primary` ou un identifiant de `GET /integrations/google-calendar/calendars`)."},"timezone":{"type":"string","description":"Fuseau IANA des horaires (ex. `Europe/Luxembourg`)."},"days":{"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6},"description":"Jours proposés, 0 = dimanche … 6 = samedi."},"from":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Début de la plage horaire (HH:MM)."},"to":{"type":"string","pattern":"^\\d{2}:\\d{2}$","description":"Fin de la plage horaire (HH:MM), après `from`."},"duration_minutes":{"type":"integer","minimum":10,"maximum":240,"description":"Durée d'un rendez-vous."},"buffer_minutes":{"type":"integer","minimum":0,"maximum":120,"description":"Marge laissée libre avant et après chaque évènement existant."},"min_notice_hours":{"type":"number","minimum":0,"maximum":336,"description":"Délai minimum avant le premier créneau proposé."},"max_days_ahead":{"type":"integer","minimum":1,"maximum":60,"description":"Horizon maximum des créneaux proposés, en jours."},"add_meet":{"type":"boolean","description":"Ajouter un lien Google Meet au rendez-vous."},"title_template":{"type":"string","maxLength":200,"description":"Titre du rendez-vous, variables du lead acceptées (`{{companyName}}`…)."},"description_template":{"type":"string","maxLength":2000,"description":"Description du rendez-vous, variables du lead acceptées."},"check_calendars":{"type":"array","items":{"type":"string"},"description":"Agendas supplémentaires dont les évènements bloquent aussi des créneaux."}},"required":["calendar_id","timezone","days","from","to","duration_minutes","buffer_minutes","min_notice_hours","max_days_ahead","add_meet","title_template","description_template","check_calendars"],"additionalProperties":false},{"type":"null"}],"description":"Réglages de prise de rendez-vous, `null` si rien n'est enregistré."}},"required":["configured","connected","status","account_email","last_error","public_config","settings"],"additionalProperties":false},"CrmIntegration":{"type":"object","properties":{"provider":{"type":"string","enum":["hubspot","pipedrive","salesforce"]},"connected":{"type":"boolean"},"status":{"type":"string","enum":["connected","error","disconnected"],"description":"`error` : le dernier appel au service a échoué (voir `last_error`)."},"mode":{"anyOf":[{"type":"string","enum":["oauth","token"]},{"type":"null"}],"description":"Mode de connexion, `null` si non connecté."},"account_email":{"type":["string","null"]},"account_name":{"description":"Nom du compte ou du portail côté CRM.","type":["string","null"]},"token_hint":{"description":"4 derniers caractères du jeton (mode `token`). Le jeton et les jetons OAuth ne sont jamais renvoyés.","type":["string","null"]},"last_error":{"type":["string","null"]},"settings":{"type":"object","properties":{"sync_enabled":{"type":"boolean","description":"Synchronisation automatique des leads de campagne vers le CRM."},"sync_on":{"type":"string","enum":["contacted","replied"],"description":"Création de la fiche au premier envoi (`contacted`) ou seulement à la première réponse (`replied`)."},"create_deal_on_positive":{"type":"boolean","description":"Créer une affaire (deal, opportunité) quand le lead passe à un statut d'intérêt positif."},"deal_stage":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Étape de l'affaire créée (HubSpot : `dealstage`, Pipedrive : `stage_id`, Salesforce : `StageName`). `null` : étape par défaut du CRM."},"status_map":{"type":"object","propertyNames":{"type":"string","pattern":"^(contacted|replied|-?\\d{1,6})$"},"additionalProperties":{"type":"string","maxLength":100},"description":"Statut écrit dans le CRM par évènement : clé `contacted`, `replied` ou code de statut d'intérêt (`1`, `-1`…), valeur = statut du CRM (HubSpot : `hs_lead_status`, Salesforce : `Status` du lead ; ignoré pour Pipedrive, qui reçoit une note). Une valeur vide retire l'entrée."}},"required":["sync_enabled","sync_on","create_deal_on_positive","deal_stage","status_map"],"additionalProperties":false,"description":"Réglages de synchronisation (valeurs par défaut du CRM si non connecté)."},"oauth_available":{"type":"boolean","description":"L'application OAuth Replexa de ce CRM est configurée sur l'instance."},"token_available":{"type":"boolean","description":"Connexion par jeton possible (HubSpot, Pipedrive ; jamais Salesforce)."}},"required":["provider","connected","status","mode","account_email","account_name","token_hint","last_error","settings","oauth_available","token_available"],"additionalProperties":false},"AirtableBase":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la base (`app…`)."},"name":{"type":"string"},"permissionLevel":{"type":"string","description":"Droits du jeton sur la base (`read`, `edit`, `create`…)."}},"required":["id","name","permissionLevel"],"additionalProperties":false},"AirtableTable":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la table (`tbl…`)."},"name":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","description":"Type de champ Airtable (`singleLineText`, `email`…)."}},"required":["name","type"],"additionalProperties":false}}},"required":["id","name","fields"],"additionalProperties":false},"GoogleCalendar":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'agenda, à utiliser dans `calendar_id` ou `check_calendars`."},"summary":{"type":"string"},"primary":{"type":"boolean"},"accessRole":{"type":"string","description":"Droits du compte connecté (`owner`, `writer`, `reader`, `freeBusyReader`)."}},"required":["id","summary","primary","accessRole"],"additionalProperties":false},"CalendarSlot":{"type":"object","properties":{"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Début du créneau (UTC)."},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Fin du créneau (UTC)."},"label":{"type":"string","description":"Libellé en français dans le fuseau des réglages (« mercredi 21 octobre à 10:00 »)."}},"required":["start","end","label"],"additionalProperties":false},"CrmContact":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la fiche dans le CRM (contact HubSpot, personne Pipedrive, lead Salesforce)."},"email":{"type":["string","null"]},"name":{"type":["string","null"]},"company":{"type":["string","null"]},"status":{"description":"Statut côté CRM (HubSpot `hs_lead_status`, Salesforce `Status`), absent pour Pipedrive.","type":["string","null"]}},"required":["id","email","name","company"],"additionalProperties":false},"Workspace":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant du workspace."},"name":{"type":"string"},"slug":{"type":["string","null"]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Propriétaire (`user_id`)."},"plan":{"type":"string","description":"Plan : `trial`, `starter`, `growth`, `scale` ou `internal`."},"subscription_status":{"type":"string","enum":["trialing","active","past_due","canceled","unpaid","incomplete","incomplete_expired","paused"]},"trial_ends_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Fin de l'essai gratuit."},"current_period_end":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Fin de la période d'abonnement en cours."},"cancel_at_period_end":{"type":"boolean","description":"Résiliation programmée à la fin de la période."},"limits":{"type":"object","properties":{"max_mailboxes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Boîtes d'envoi, null = illimité."},"max_leads_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Leads créés par mois civil (UTC), null = illimité."},"max_emails_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Emails envoyés par mois civil, null = illimité. Seuls les envois de campagne sont bloqués une fois le quota atteint."},"ai_credits_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Crédits IA par mois civil, null = illimité."},"max_members":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Membres du workspace (invitations nominatives en cours comprises), null = illimité."}},"additionalProperties":false,"description":"Limites propres au workspace, qui remplacent celles du plan (voir `GET /billing` pour les limites effectives)."},"require_mfa":{"type":"boolean","description":"Double authentification obligatoire pour accéder au workspace depuis l'interface."},"settings":{"type":"object","properties":{"auto_interest":{"type":"boolean","description":"L'IA attribue un statut d'intérêt à chaque réponse reçue."},"auto_interest_update_existing_labels":{"type":"boolean","description":"L'IA peut remplacer un statut déjà posé (jamais un statut posé à la main)."},"auto_ooo_status":{"type":"boolean","description":"Marque automatiquement les absences du bureau."},"auto_protect_campaigns":{"type":"boolean","description":"Met en pause une campagne dont le taux de bounce dépasse le seuil."},"auto_protect_campaigns_bounce_rate_threshold":{"type":"number","minimum":1,"maximum":50,"description":"Seuil de bounce en %, de 1 à 50."},"default_opportunity_value":{"type":"number","minimum":0,"description":"Valeur par défaut d'une opportunité, pour les statistiques."},"notification_recipients_positive_reply":{"type":"array","items":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"description":"Adresses prévenues à chaque réponse positive."}},"required":["auto_interest","auto_interest_update_existing_labels","auto_ooo_status","auto_protect_campaigns","auto_protect_campaigns_bounce_rate_threshold","default_opportunity_value","notification_recipients_positive_reply"],"additionalProperties":false},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."}},"required":["id","name","slug","owner_id","plan","subscription_status","trial_ends_at","current_period_end","cancel_at_period_end","limits","require_mfa","settings","timestamp_created","timestamp_updated"],"additionalProperties":false},"WorkspaceMember":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"role":{"type":"string","enum":["owner","admin","member","viewer"]},"email":{"type":["string","null"]},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"joined_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Arrivée dans le workspace."},"is_you":{"type":"boolean","description":"true pour l'utilisateur de la requête (créateur de la clé API)."}},"required":["user_id","role","email","first_name","last_name","joined_at","is_you"],"additionalProperties":false},"WorkspaceInvitation":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de l'invitation."},"email":{"description":"Invité, ou null pour un lien partageable.","type":["string","null"]},"role":{"type":"string","enum":["admin","member","viewer"],"description":"Rôle donné à l'arrivée."},"max_uses":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 pour une invitation nominative."},"uses":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Expiration."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["id","email","role","max_uses","uses","expires_at","timestamp_created"],"additionalProperties":false},"ApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Identifiant de la clé."},"organization_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Workspace de la clé."},"name":{"type":"string"},"key_prefix":{"type":"string","description":"Premiers caractères de la clé, pour la reconnaître. La clé complète n'est montrée qu'à sa création."},"scopes":{"type":"array","items":{"type":"string"},"description":"Scopes `ressource:action` (`all:all` : tout)."},"role":{"type":"string","enum":["admin","member","viewer"],"description":"Rôle de la clé, jamais supérieur à celui de son créateur."},"created_by":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Expiration, null si la clé n'expire pas."},"timestamp_last_used":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Dernière utilisation."},"timestamp_revoked":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Révocation, null si la clé est active."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."},"timestamp_updated":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Dernière modification."}},"required":["id","organization_id","name","key_prefix","scopes","role","created_by","expires_at","timestamp_last_used","timestamp_revoked","timestamp_created","timestamp_updated"],"additionalProperties":false},"Billing":{"type":"object","properties":{"plan":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"price_cents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Prix mensuel TTC en centimes (TVA luxembourgeoise de 17 % incluse ; sans TVA en autoliquidation), null si non affiché."},"price_yearly_cents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Prix annuel TTC en centimes (10 % de moins que douze mois), null si le plan ne se vend pas à l'année."},"currency":{"type":"string"},"purchasable":{"type":"boolean"},"sort":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"max_mailboxes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Boîtes d'envoi, null = illimité."},"max_leads_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Leads créés par mois civil (UTC), null = illimité."},"max_emails_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Emails envoyés par mois civil, null = illimité. Seuls les envois de campagne sont bloqués une fois le quota atteint."},"ai_credits_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Crédits IA par mois civil, null = illimité."},"max_members":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Membres du workspace (invitations nominatives en cours comprises), null = illimité."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["id","name","description","price_cents","price_yearly_cents","currency","purchasable","sort","max_mailboxes","max_leads_per_month","max_emails_per_month","ai_credits_per_month","max_members","timestamp_created"],"additionalProperties":false,"description":"Plan actuel du workspace."},"limits":{"type":"object","properties":{"max_mailboxes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Boîtes d'envoi, null = illimité."},"max_leads_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Leads créés par mois civil (UTC), null = illimité."},"max_emails_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Emails envoyés par mois civil, null = illimité. Seuls les envois de campagne sont bloqués une fois le quota atteint."},"ai_credits_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Crédits IA par mois civil, null = illimité."},"max_members":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Membres du workspace (invitations nominatives en cours comprises), null = illimité."}},"required":["max_mailboxes","max_leads_per_month","max_emails_per_month","ai_credits_per_month","max_members"],"additionalProperties":false,"description":"Limites effectives : celles du plan, remplacées par les limites propres au workspace."},"subscription_status":{"type":"string","description":"Statut de l'abonnement : `none` (jamais abonné), puis les statuts Stripe `trialing`, `active`, `past_due`, `canceled`, `unpaid`, `incomplete`, `incomplete_expired`, `paused`."},"trial_ends_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Fin de l'essai gratuit."},"current_period_end":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Fin de la période en cours."},"cancel_at_period_end":{"type":"boolean"},"sending_blocked":{"type":"boolean","description":"Pas d'abonnement utilisable (aucun abonnement, impayé, abonnement terminé, essai expiré) : envois refusés, et l'interface n'affiche plus que le choix du plan. L'API reste lisible."},"blocked_reason":{"description":"Raison du blocage : « Aucun abonnement », « Abonnement terminé », « Paiement en attente » ou « Essai terminé ».","type":["string","null"]},"has_customer":{"type":"boolean","description":"Un client Stripe existe (portail de facturation disponible)."},"billing_interval":{"type":"string","enum":["month","year"],"description":"Rythme de facturation de l'abonnement : mensuel ou annuel."},"has_subscription":{"type":"boolean","description":"Un abonnement Stripe est en cours, essai compris : le changement de plan passe par le portail."},"usage":{"type":"object","properties":{"mailboxes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"leads_this_month":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"emails_this_month":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"ai_credits_this_month":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"members":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["mailboxes","leads_this_month","emails_this_month","ai_credits_this_month","members"],"additionalProperties":false,"description":"Consommation : boîtes et membres actuels, leads, emails envoyés et crédits IA depuis le 1er du mois (UTC)."},"plans":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"price_cents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Prix mensuel TTC en centimes (TVA luxembourgeoise de 17 % incluse ; sans TVA en autoliquidation), null si non affiché."},"price_yearly_cents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Prix annuel TTC en centimes (10 % de moins que douze mois), null si le plan ne se vend pas à l'année."},"currency":{"type":"string"},"purchasable":{"type":"boolean"},"sort":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"max_mailboxes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Boîtes d'envoi, null = illimité."},"max_leads_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Leads créés par mois civil (UTC), null = illimité."},"max_emails_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Emails envoyés par mois civil, null = illimité. Seuls les envois de campagne sont bloqués une fois le quota atteint."},"ai_credits_per_month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Crédits IA par mois civil, null = illimité."},"max_members":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Membres du workspace (invitations nominatives en cours comprises), null = illimité."},"timestamp_created":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Date de création."}},"required":["id","name","description","price_cents","price_yearly_cents","currency","purchasable","sort","max_mailboxes","max_leads_per_month","max_emails_per_month","ai_credits_per_month","max_members","timestamp_created"],"additionalProperties":false},"description":"Plans proposés à l'achat."},"stripe_configured":{"type":"boolean","description":"Paiement en ligne configuré sur cette instance."},"can_manage":{"type":"boolean","description":"true si l'appelant est propriétaire (seul rôle qui gère l'abonnement, depuis l'interface)."},"trial":{"type":"object","properties":{"plan_id":{"type":"string","description":"Plan qui ouvre droit à l'essai (`growth`)."},"days":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Durée de l'essai en jours (7)."},"available":{"type":"boolean","description":"false si ce workspace ou son propriétaire a déjà eu un essai."}},"required":["plan_id","days","available"],"additionalProperties":false,"description":"Essai gratuit : pris au paiement, carte obligatoire, sur un seul plan."}},"required":["plan","limits","subscription_status","trial_ends_at","current_period_end","cancel_at_period_end","sending_blocked","blocked_reason","has_customer","billing_interval","has_subscription","usage","plans","stripe_configured","can_manage","trial"],"additionalProperties":false},"Success":{"type":"object","required":["success"],"properties":{"success":{"const":true}}},"Error":{"type":"object","required":["statusCode","error","message"],"properties":{"statusCode":{"type":"integer","description":"Code HTTP, répété dans le corps."},"error":{"type":"string","description":"Libellé du code HTTP (ex. « Not Found »)."},"message":{"type":"string","description":"Explication lisible, en français ou en anglais."}}}},"responses":{"E400":{"description":"Requête invalide : paramètre ou corps non conforme au schéma, JSON illisible, référence inconnue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":400,"error":"Bad Request","message":"email: Invalid email address"}}}},"E401":{"description":"Clé API absente, invalide, révoquée ou expirée.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid or revoked API key"}}}},"E402":{"description":"Limite du plan atteinte, ou abonnement qui ne permet plus l'action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":402,"error":"Payment Required","message":"Limite du plan atteinte : 5 boîtes d'envoi"}}}},"E403":{"description":"Scope de la clé ou rôle insuffisant pour cette opération.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":403,"error":"Forbidden","message":"Missing scope campaigns:update"}}}},"E404":{"description":"Ressource introuvable dans le workspace de la clé.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":404,"error":"Not Found","message":"Campaign not found"}}}},"E409":{"description":"Conflit : une ressource avec la même valeur unique existe déjà.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":409,"error":"Conflict","message":"duplicate key value violates unique constraint"}}}},"E413":{"description":"Corps de requête supérieur à 5 Mo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":413,"error":"Payload Too Large","message":"Corps de requête trop volumineux"}}}},"E415":{"description":"Corps envoyé sans `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":415,"error":"Unsupported Media Type","message":"Content-Type: application/json requis"}}}},"E422":{"description":"Requête comprise mais impossible à traiter (refus du modèle d'IA, contenu inexploitable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":422,"error":"Unprocessable Entity","message":"Variation refusée par le modèle"}}}},"E429":{"description":"Trop de requêtes : attendez le nombre de secondes indiqué par l'en-tête `Retry-After`.","headers":{"Retry-After":{"description":"Secondes à attendre avant de réessayer.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":429,"error":"Too Many Requests","message":"Trop de requêtes, réessayez dans un instant"}}}},"E502":{"description":"Le service tiers appelé (CRM, Google, Stripe, serveur mail…) a répondu par une erreur.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":502,"error":"Bad Gateway","message":"Le service distant a répondu 500"}}}},"E503":{"description":"Fonction non configurée sur cette instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"statusCode":503,"error":"Service Unavailable","message":"Paiement non configuré"}}}}}}}