Intégrations

Créez et gérez des connexions à des bases de données, à des services d'envoi d'e-mails, à des CRM et à Google Drive, puis utilisez-les pour interroger, envoyer, rechercher et écrire : ce sont les mêmes connexions que celles du chat, des agents et des workflows.

11 min de lecture · Mis à jour le 28 septembre 2026

Les intégrations permettent à StickyPrompts d’agir sur vos propres systèmes. Avec l’API, vous pouvez créer des connexions puis les utiliser directement : exécuter du SQL sur une base de données, envoyer un e-mail, rechercher ou mettre à jour des données dans un CRM, et transférer des fichiers depuis et vers Google Drive. Tout ce qui est décrit ici repose sur les mêmes mécanismes que ceux qu’utilise l’application lorsque quelqu’un en fait la demande dans le chat.

Tous les chemins sont relatifs à https://api.stickyprompts.com/api/v1. La clé agit au nom de son propriétaire : les mêmes règles de partage et d’administration que dans l’application s’appliquent.

Concepts

Fournisseurs

:provider dans les chemins, et provider dans les réponses, utilisent exactement ces chaînes :

FournisseurFamilleMode de connexionConnexions
mysql, mariadb, postgres, sqlserverbase de donnéesidentifiantsillimitées
smtp, postmark, resend, sendgride-mailidentifiantsune seule connexion e-mail au total par propriétaire, quel que soit le fournisseur
pipedriveCRMidentifiants1
activecampaignCRMidentifiants1
brevoCRMidentifiants1
google_drivestockageOAuth dans un navigateur1, personnelle uniquement

Les limites s’entendent par propriétaire : par utilisateur pour les connexions personnelles, par espace de travail pour les connexions partagées.

Portée

Chaque connexion est personal (seul son propriétaire la voit et l’utilise) ou workspace (tous les membres de l’espace de travail peuvent l’utiliser). Seuls les propriétaires et les administrateurs de l’espace de travail peuvent créer, modifier ou supprimer une connexion d’espace de travail, ou lire les informations enregistrées ; tout membre peut en revanche l’utiliser : l’interroger, envoyer des messages par son intermédiaire, lire des fiches CRM et, si l’accès en écriture est activé, en écrire. Une connexion que vous ne pouvez pas voir répond 404, jamais 403.

Identifiants ou OAuth

  • Les connexions base de données, e-mail et CRM se créent en un seul appel, avec les identifiants dans le corps. Le serveur les vérifie d’abord auprès du fournisseur : il ouvre la connexion à la base de données, s’authentifie auprès du serveur SMTP ou envoie un message de test via Postmark, Resend ou SendGrid. Un client purement API peut mener l’opération de bout en bout.
  • Google Drive utilise OAuth. L’appel de connexion renvoie une auth_url ; une personne doit l’ouvrir et accepter l’écran de consentement de Google. Votre code peut transmettre le lien à un utilisateur et interroger GET /integration/connections?provider=google_drive jusqu’à ce que la connexion apparaisse.

Aucun endpoint ne renvoie jamais les secrets.

Statut

Le status d’une connexion vaut active, needs_reauth, revoked ou error. Toute route de connexion appelée sur une connexion non active répond 409 {"error":"reconnect_required"}. Aujourd’hui, seules les connexions Google Drive peuvent quitter l’état active ; rétablissez-les avec la reconnexion.

Erreurs

StatutExemple de corpsSignification
400"invalid request", "query is required"Entrée mal formée.
403"you do not have permission to manage this connection"Connexion d’espace de travail, et vous n’êtes ni propriétaire ni administrateur.
403"this connection is read-only; enable write access on the connection to create or edit records"Écriture CRM sans accès en écriture.
404"integration is not connected or does not exist"Connexion inconnue, ou qui ne vous appartient pas.
409"reconnect_required", "connection limit reached for this integration"Nouvelle autorisation nécessaire, ou limite dépassée.
413"the attachments are too large to send"
422"failed to connect to the integration with the given credentials: ..."Identifiants refusés lors de la connexion ou de la mise à jour.
422"query is not a single read-only select statement"Requête SQL non autorisée au niveau d’autorisation de la connexion.
422"the message was rejected: ..."Le fournisseur d’e-mail a refusé le message.
501"integration provider does not support this capability: ..."Par exemple, des affaires (deals) sur un CRM qui n’en gère pas.
502"failed to send the message: ...", "failed to reach the crm provider: ..."Le fournisseur en amont a échoué.
504"query timed out"La requête de base de données a dépassé son délai d’expiration.
500"internal server error"Erreurs non répertoriées, y compris les erreurs SQL levées par la base de données elle-même.

Catalogue et connexions

GET /integration

GET /api/v1/integration
Autorisation integrations_get

Le catalogue des fournisseurs, avec les capacités de chacun et le nombre de connexions dont vous disposez déjà.

[
  {
    "provider": "postgres",
    "display_name": "PostgreSQL",
    "capabilities": ["test_connection", "schema_browse", "query"],
    "availability": "available",
    "connection_count": 1,
    "max_connections": 0
  }
]

max_connections: 0 signifie illimité. La limite commune d’une seule connexion e-mail n’apparaît pas ici.

GET /integration/ssh-tunnel/public-key

GET /api/v1/integration/ssh-tunnel/public-key
Autorisation integrations_get

Les connexions de base de données peuvent atteindre une base privée via un hôte de rebond SSH (jump host). Ajoutez cette clé publique au fichier authorized_keys de l’utilisateur SSH sur votre hôte de rebond, et autorisez l’adresse de StickyPrompts dans votre pare-feu.

{ "public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... stickyprompts" }

POST /integration/:provider/connect

POST /api/v1/integration/:provider/connect

Crée une nouvelle connexion (elle n’en remplace jamais une existante). Le corps est un objet à plat : les champs communs, plus ceux propres au fournisseur.

Champs communs du corps
name string obligatoire
Un nom que chacun reconnaîtra, par exemple « Northwind Retail DB ».
description string facultatif
Facultatif.
scope string obligatoire
personal ou workspace. workspace exige un propriétaire ou un administrateur de l’espace de travail.
database_permission string facultatif par défaut read_only
Bases de données uniquement : read_only, create_update ou full_access. Voir les niveaux d’autorisation.
Champs base de données (mysql, mariadb, postgres, sqlserver)
host string obligatoire
Nom d’hôte tel que StickyPrompts le voit, ou tel que l’hôte de rebond le voit si vous passez par SSH.
port integer facultatif
Par défaut 3306 (MySQL, MariaDB), 5432 (PostgreSQL), 1433 (SQL Server).
database string obligatoire
schema string facultatif
Par défaut public pour PostgreSQL, dbo pour SQL Server.
username string obligatoire
Utilisez un utilisateur dédié, doté des privilèges strictement nécessaires.
password string obligatoire
ssl_mode string facultatif
PostgreSQL : disable, require (par défaut), verify-ca, verify-full. MySQL/MariaDB : true, false, skip-verify, preferred (par défaut). SQL Server : true (par défaut), skip-verify, false.
ssh_host string facultatif
Passe par cet hôte de rebond SSH.
ssh_port integer facultatif
ssh_username string facultatif
Obligatoire avec ssh_host.
Champs e-mail (smtp, postmark, resend, sendgrid)
default_from_email string obligatoire
L’expéditeur par défaut. Pour Postmark, Resend et SendGrid, il doit déjà s’agir d’un expéditeur accepté par votre fournisseur : le test de connexion envoie un véritable message de test.
default_from_name string facultatif
default_reply_to string facultatif
server_token string facultatif
Postmark.
api_key string facultatif
Resend et SendGrid.
host, port, username, password, encryption various facultatif
SMTP. encryption vaut starttls (par défaut), ssl ou none ; port vaut 587 par défaut, ou 465 avec ssl.
Champs CRM
api_token string facultatif
Pipedrive (obligatoire).
api_url, api_key string facultatif
ActiveCampaign (tous deux obligatoires ; api_url est l’URL de votre compte).
api_key string facultatif
Brevo (obligatoire).
allow_write boolean facultatif par défaut false
Sans cette option, la connexion est en lecture seule : l’ajout ou la modification de contacts et la création d’affaires répondent 403.
curl -X POST https://api.stickyprompts.com/api/v1/integration/postgres/connect \
  -H "Authorization: Bearer $STICKY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Northwind Retail DB",
    "scope": "workspace",
    "database_permission": "read_only",
    "host": "localhost",
    "port": 5432,
    "database": "retail",
    "schema": "public",
    "username": "sp_reader",
    "password": "********",
    "ssl_mode": "disable",
    "ssh_host": "bastion.northwind.example",
    "ssh_port": 22,
    "ssh_username": "stickyprompts"
  }'
import os, requests

r = requests.post(
    "https://api.stickyprompts.com/api/v1/integration/postmark/connect",
    headers={"Authorization": f"Bearer {os.environ['STICKY_API_KEY']}"},
    json={
        "name": "Northwind Mailer",
        "scope": "workspace",
        "default_from_email": "team@northwind.example",
        "default_from_name": "Northwind Team",
        "server_token": os.environ["POSTMARK_SERVER_TOKEN"],
    },
)
print(r.status_code, r.json())   # 200 {"connection_id": 42}
const res = await fetch("https://api.stickyprompts.com/api/v1/integration/pipedrive/connect", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.STICKY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Pipedrive - Sales",
    scope: "workspace",
    api_token: process.env.PIPEDRIVE_TOKEN,
    allow_write: true,
  }),
});
console.log(res.status, await res.json()); // 200 {"connection_id": 43}

Réponse 200 {"connection_id": 42}. Pour google_drive, la réponse est à la place 200 {"auth_url": "..."} : envoyez une personne vers cette URL pour finaliser la connexion.

GET /integration/connections

GET /api/v1/integration/connections

Toutes les connexions que vous pouvez voir (les vôtres, plus celles partagées dans votre espace de travail), de la plus récente à la plus ancienne. Paramètre facultatif ?provider=<provider>.

[
  {
    "id": 42,
    "provider": "postgres",
    "name": "Northwind Retail DB",
    "description": "Demo retail data: stores, orders, products, customers.",
    "scope": "workspace",
    "status": "active",
    "account_name": "sp_reader@localhost:5432/retail",
    "connected_at": "2026-09-28T12:55:00Z",
    "database_permission": "read_only"
  }
]

account_name est un libellé non secret : user@host:port/database pour les bases de données, l’expéditeur par défaut pour l’e-mail, l’URL du compte pour ActiveCampaign. L’accès en écriture CRM ne figure pas dans cette liste ; lisez-le avec GET .../crm/connection.

PATCH /integration/connections/:connectionId

PATCH /api/v1/integration/connections/:connectionId

Renomme une connexion, change son niveau d’autorisation de base de données ou renouvelle ses identifiants. Envoyez name à chaque fois (le nom actuel si vous ne le changez pas). description est toujours écrit : l’omettre l’efface. Seuls les champs du fournisseur que vous envoyez sont modifiés ; si un champ d’identifiant est présent, la configuration fusionnée est revérifiée avant l’enregistrement (422 en cas d’échec). Pour les bases de données, "ssh_host": "" désactive le tunnel SSH. Renvoie 200 avec un corps vide.

DELETE /integration/connections/:connectionId

DELETE /api/v1/integration/connections/:connectionId

Supprime la connexion et ses identifiants enregistrés. Pour Google Drive, l’autorisation est d’abord révoquée auprès de Google. Renvoie 204.

POST /integration/connections/:connectionId/reconnect

POST /api/v1/integration/connections/:connectionId/reconnect

Relance un consentement OAuth pour une connexion Google Drive, en conservant son ID et son nom. Renvoie 200 {"auth_url": "..."}. Les fournisseurs à identifiants répondent 501 ; mettez-les à jour avec PATCH.

Bases de données

Niveaux d’autorisation

Le database_permission de la connexion détermine quelles requêtes SQL l’endpoint de requête accepte, quelles que soient les autorisations de la clé API :

NiveauAutorisé
read_onlyExactement une instruction SELECT ou WITH.
create_updateExactement une instruction SELECT, WITH, INSERT ou UPDATE.
full_accessTout ce que l’utilisateur de la base de données peut exécuter. Aucun filtrage des instructions.

Pour read_only et create_update, l’instruction entière est analysée à la recherche de mots-clés interdits : une requête en lecture seule qui contient simplement un mot comme update dans un nom de colonne ou dans une chaîne est donc refusée. Pour MySQL, MariaDB et PostgreSQL, les sessions en lecture seule sont en outre ouvertes en mode lecture seule ; SQL Server s’appuie uniquement sur la vérification des mots-clés. Dans tous les cas, connectez-vous avec un utilisateur de base de données qui ne dispose que des droits que vous comptez accorder.

GET /integration/connections/:connectionId/database/schema

GET /api/v1/integration/connections/:connectionId/database/schema

Toutes les tables et vues du schéma de la connexion, avec leurs colonnes :

{
  "schema": {
    "name": "public",
    "tables": [
      {
        "schema": "public",
        "name": "demo_orders",
        "columns": [
          { "name": "id", "data_type": "integer", "nullable": false },
          { "name": "customer_id", "data_type": "integer", "nullable": false },
          { "name": "status", "data_type": "text", "nullable": true }
        ]
      }
    ]
  }
}

GET /integration/connections/:connectionId/database/connection

GET /api/v1/integration/connections/:connectionId/database/connection

Les informations de connexion enregistrées, sans le mot de passe. Pour les connexions d’espace de travail, réservé aux propriétaires et aux administrateurs. Les champs laissés vides reviennent sous la forme 0 ou "", même si une valeur par défaut a servi à établir la connexion.

POST /integration/connections/:connectionId/database/query

POST /api/v1/integration/connections/:connectionId/database/query
Corps de la requête
query string obligatoire
Une seule instruction SQL.
row_limit integer facultatif par défaut 100
1000 au maximum.
timeout_seconds integer facultatif par défaut 10
30 au maximum.
curl -X POST https://api.stickyprompts.com/api/v1/integration/connections/42/database/query \
  -H "Authorization: Bearer $STICKY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT c.name, SUM(o.total) AS revenue FROM demo_orders o JOIN demo_customers c ON c.id = o.customer_id GROUP BY c.name ORDER BY revenue DESC LIMIT 5"}'
import os, requests

r = requests.post(
    "https://api.stickyprompts.com/api/v1/integration/connections/42/database/query",
    headers={"Authorization": f"Bearer {os.environ['STICKY_API_KEY']}"},
    json={"query": "SELECT name, city FROM demo_customers ORDER BY name", "row_limit": 50},
)
data = r.json()
rows = [dict(zip(data["columns"], row)) for row in data["rows"]]
const res = await fetch(
  "https://api.stickyprompts.com/api/v1/integration/connections/42/database/query",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.STICKY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ query: "SELECT name, city FROM demo_customers ORDER BY name" }),
  },
);
const { columns, rows, truncated } = await res.json();

Réponse pour un SELECT :

{
  "columns": ["name", "revenue"],
  "rows": [["Hawthorne Goods", "18240.00"], ["Cedar & Pine Outfitters", "15110.50"]],
  "row_count": 2,
  "truncated": false
}

truncated: true signifie que d’autres lignes existaient au-delà de row_limit. Les colonnes numériques arrivent souvent sous forme de chaînes. Les autres instructions (autorisées aux niveaux supérieurs) ne renvoient que row_count, le nombre de lignes affectées. Les erreurs SQL levées par la base de données renvoient 500 sans le message de la base : testez donc d’abord vos requêtes dans un client de base de données.

E-mail

Les e-mails partent toujours avec les identifiants du compte connecté ; StickyPrompts ne fournit aucun expéditeur.

GET /integration/connections/:connectionId/email/connection

GET /api/v1/integration/connections/:connectionId/email/connection

Les paramètres d’expédition (provider, default_from_email, default_from_name, default_reply_to, plus l’hôte, le port, le nom d’utilisateur et le chiffrement pour SMTP). Les tokens et les mots de passe ne sont jamais renvoyés. Pour les connexions d’espace de travail, réservé aux propriétaires et aux administrateurs.

POST /integration/connections/:connectionId/email/send

POST /api/v1/integration/connections/:connectionId/email/send
Corps de la requête
to Address[] obligatoire
Au moins un {"email": "...", "name": "..."}.
cc, bcc Address[] facultatif
to, cc et bcc réunis : 50 destinataires au maximum.
reply_to Address[] facultatif
Par défaut, l’adresse de réponse de la connexion.
subject string obligatoire
html_body string facultatif
Envoyez html_body, text_body ou les deux.
text_body string facultatif
from_email, from_name string facultatif
Remplacent l’expéditeur pour ce message. Votre fournisseur peut refuser un expéditeur non vérifié.
attachment_file_ids integer[] facultatif
Jusqu’à 10 fichiers StickyPrompts qui vous appartiennent. Limites de taille après encodage : SMTP 25 Mo, Postmark 10 Mo, SendGrid 30 Mo, Resend 40 Mo.
curl -X POST https://api.stickyprompts.com/api/v1/integration/connections/41/email/send \
  -H "Authorization: Bearer $STICKY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": [{ "email": "sales@northwind.example", "name": "Sales team" }],
    "subject": "Pipedrive: Deals at Proposal Made",
    "html_body": "<p>2 deals at Proposal Made, worth $28,788.</p>",
    "text_body": "2 deals at Proposal Made, worth $28,788."
  }'

Réponse 200 {"message_id": "<...>", "provider": "postmark"} : l’ID attribué par le fournisseur, pratique pour retrouver le message dans son tableau de bord.

CRM

Les lectures fonctionnent sur toute connexion CRM. Les écritures (ajout ou modification de contacts, création d’affaires) nécessitent allow_write sur la connexion.

Contact : email (obligatoire pour toute écriture, et clé de recherche pour les modifications), first_name, last_name, phone, company, custom_fields (propres au fournisseur), list_ids (Brevo, ActiveCampaign) et tag_ids (ActiveCampaign). Les résultats sont renvoyés sous la forme {"remote_id", "provider", "contact"}.

Affaire (deal) : title, value, currency, contact_email (doit correspondre à un contact existant) et stage (un libellé libre). Les résultats sont renvoyés sous la forme {"remote_id", "provider", "deal"}.

GET /integration/connections/:connectionId/crm/connection

GET /api/v1/integration/connections/:connectionId/crm/connection

{"provider": "pipedrive", "allow_write": true} (plus api_url pour ActiveCampaign).

GET /integration/connections/:connectionId/crm/contacts

GET /api/v1/integration/connections/:connectionId/crm/contacts

Recherchez des contacts avec query (obligatoire) et des filtres facultatifs propres au fournisseur, en notation entre crochets, par exemple ?query=priya&filters[organization_id]=1. Pipedrive et ActiveCampaign effectuent une recherche en texte libre ; Brevo recherche une seule adresse e-mail ou un seul ID exact.

GET /integration/connections/:connectionId/crm/contacts/list

GET /api/v1/integration/connections/:connectionId/crm/contacts/list

Parcourez les contacts. Indiquez limit (50 par défaut), puis paginez avec cursor (Pipedrive : passez le next_cursor précédent) ou offset (ActiveCampaign, Brevo). Renvoie {"contacts": [...], "has_more": true, "next_cursor": "..."}.

POST /integration/connections/:connectionId/crm/contacts

POST /api/v1/integration/connections/:connectionId/crm/contacts

Ajoute un contact. Un nouveau contact est toujours créé, même si l’adresse e-mail existe déjà : faites donc d’abord une recherche.

{ "email": "priya.raman@hawthornegoods.example", "first_name": "Priya", "last_name": "Raman", "company": "Hawthorne Goods" }

PATCH /integration/connections/:connectionId/crm/contacts

PATCH /api/v1/integration/connections/:connectionId/crm/contacts

Modifie le contact correspondant à cet email ; seuls les champs envoyés sont modifiés (envoyez "" pour en vider un). Ne crée jamais de contact : 404 "no matching contact was found in the crm to update".

GET /integration/connections/:connectionId/crm/deals

GET /api/v1/integration/connections/:connectionId/crm/deals

Recherchez des affaires par titre ou par l’adresse e-mail du contact associé avec query, plus des filtres propres au fournisseur (pour Pipedrive : status, person_id, organization_id, exact_match).

GET /integration/connections/:connectionId/crm/deals/list

GET /api/v1/integration/connections/:connectionId/crm/deals/list

Parcourez les affaires, avec la même pagination que pour les contacts. Les filtres Pipedrive incluent stage_id, status, owner_id et pipeline_id.

POST /integration/connections/:connectionId/crm/deals

POST /api/v1/integration/connections/:connectionId/crm/deals
{ "title": "Cedar & Pine - Scale plan, 42 stores", "value": 4788, "currency": "USD", "contact_email": "marcus.webb@cedarpine.example", "stage": "Proposal Made" }

404 si aucun contact ne possède cette adresse e-mail.

GET /integration/connections/:connectionId/crm/lists, /crm/tags

GET /api/v1/integration/connections/:connectionId/crm/lists

Les listes (Brevo, ActiveCampaign) et les tags (ActiveCampaign), sous la forme [{"id": "12", "name": "Newsletter"}], à utiliser dans les filtres et dans les list_ids / tag_ids d’un contact. Les autres fournisseurs répondent 501.

Google Drive

Les routes de stockage agissent toujours sur votre propre connexion Drive personnelle et prennent le fournisseur dans le chemin : /integration/google_drive/storage/.... Les ID de dossier et d’élément valent root ou un ID Drive.

GET /integration/:provider/storage/entries

GET /api/v1/integration/:provider/storage/entries

Liste le contenu d’un dossier : folder_id (par défaut root), page_token, page_size (de 1 à 200, 100 par défaut), kind (folder ou file). Renvoie {"entries": [...], "next_page_token": "", "breadcrumbs": [...]}. Chaque élément comporte id, name, kind, mime_type, size, modified_at, web_url, importable et import_name (les Docs et Drawings sont importés en PDF, les Sheets en XLSX, les Slides en PPTX).

GET /integration/:provider/storage/search

GET /api/v1/integration/:provider/storage/search

query (obligatoire), avec la même pagination et les mêmes filtres.

GET /integration/:provider/storage/entry/:entryId

GET /api/v1/integration/:provider/storage/entry/:entryId

POST /integration/:provider/storage/import

POST /api/v1/integration/:provider/storage/import

Copie de 1 à 20 éléments Drive (entry_ids) dans StickyPrompts sous forme de fichiers ordinaires, éventuellement rattachés à un project_id. Chaque élément réussit ou échoue indépendamment des autres ; vérifiez donc toujours failed dans la réponse {"files": [...], "failed": [{"entry_id": "...", "error": "..."}]}. Jusqu’à 100 Mo par fichier.

POST /integration/:provider/storage/export

POST /api/v1/integration/:provider/storage/export

Copie un fichier StickyPrompts qui vous appartient (file_id) dans un dossier Drive (folder_id, root autorisé), en le renommant éventuellement avec name.