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.
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 :
| Fournisseur | Famille | Mode de connexion | Connexions |
|---|---|---|---|
mysql, mariadb, postgres, sqlserver | base de données | identifiants | illimitées |
smtp, postmark, resend, sendgrid | identifiants | une seule connexion e-mail au total par propriétaire, quel que soit le fournisseur | |
pipedrive | CRM | identifiants | 1 |
activecampaign | CRM | identifiants | 1 |
brevo | CRM | identifiants | 1 |
google_drive | stockage | OAuth dans un navigateur | 1, 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 interrogerGET /integration/connections?provider=google_drivejusqu’à 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
| Statut | Exemple de corps | Signification |
|---|---|---|
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
/api/v1/integration 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
/api/v1/integration/ssh-tunnel/public-key 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
/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.
-
namestring obligatoire - Un nom que chacun reconnaîtra, par exemple « Northwind Retail DB ».
-
descriptionstring facultatif - Facultatif.
-
scopestring obligatoire personalouworkspace.workspaceexige un propriétaire ou un administrateur de l’espace de travail.-
database_permissionstring facultatif par défautread_only - Bases de données uniquement :
read_only,create_updateoufull_access. Voir les niveaux d’autorisation.
-
hoststring 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.
-
portinteger facultatif - Par défaut 3306 (MySQL, MariaDB), 5432 (PostgreSQL), 1433 (SQL Server).
-
databasestring obligatoire -
schemastring facultatif - Par défaut
publicpour PostgreSQL,dbopour SQL Server. -
usernamestring obligatoire - Utilisez un utilisateur dédié, doté des privilèges strictement nécessaires.
-
passwordstring obligatoire -
ssl_modestring 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_hoststring facultatif - Passe par cet hôte de rebond SSH.
-
ssh_portinteger facultatif -
ssh_usernamestring facultatif - Obligatoire avec
ssh_host.
-
default_from_emailstring 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_namestring facultatif -
default_reply_tostring facultatif -
server_tokenstring facultatif - Postmark.
-
api_keystring facultatif - Resend et SendGrid.
-
host, port, username, password, encryptionvarious facultatif - SMTP.
encryptionvautstarttls(par défaut),sslounone;portvaut 587 par défaut, ou 465 avecssl.
-
api_tokenstring facultatif - Pipedrive (obligatoire).
-
api_url, api_keystring facultatif - ActiveCampaign (tous deux obligatoires ;
api_urlest l’URL de votre compte). -
api_keystring facultatif - Brevo (obligatoire).
-
allow_writeboolean facultatif par défautfalse - 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
/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
/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
/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
/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 :
| Niveau | Autorisé |
|---|---|
read_only | Exactement une instruction SELECT ou WITH. |
create_update | Exactement une instruction SELECT, WITH, INSERT ou UPDATE. |
full_access | Tout 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
/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
/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
/api/v1/integration/connections/:connectionId/database/query -
querystring obligatoire - Une seule instruction SQL.
-
row_limitinteger facultatif par défaut100 - 1000 au maximum.
-
timeout_secondsinteger facultatif par défaut10 - 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.
Les e-mails partent toujours avec les identifiants du compte connecté ; StickyPrompts ne fournit aucun expéditeur.
GET /integration/connections/:connectionId/email/connection
/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
/api/v1/integration/connections/:connectionId/email/send -
toAddress[] obligatoire - Au moins un
{"email": "...", "name": "..."}. -
cc, bccAddress[] facultatif to,ccetbccréunis : 50 destinataires au maximum.-
reply_toAddress[] facultatif - Par défaut, l’adresse de réponse de la connexion.
-
subjectstring obligatoire -
html_bodystring facultatif - Envoyez
html_body,text_bodyou les deux. -
text_bodystring facultatif -
from_email, from_namestring facultatif - Remplacent l’expéditeur pour ce message. Votre fournisseur peut refuser un expéditeur non vérifié.
-
attachment_file_idsinteger[] 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
/api/v1/integration/connections/:connectionId/crm/connection {"provider": "pipedrive", "allow_write": true} (plus api_url pour ActiveCampaign).
GET /integration/connections/:connectionId/crm/contacts
/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
/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
/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
/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
/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
/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
/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
/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
/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
/api/v1/integration/:provider/storage/search query (obligatoire), avec la même pagination et les mêmes filtres.
GET /integration/:provider/storage/entry/:entryId
/api/v1/integration/:provider/storage/entry/:entryId POST /integration/:provider/storage/import
/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
/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.