Integrazioni

Crea e gestisci connessioni a database, servizi di invio email, CRM e Google Drive, poi usale per eseguire query, inviare, cercare e scrivere: sono le stesse connessioni usate da chat, agenti e workflow.

10 min di lettura · Aggiornato il 28 settembre 2026

Le integrazioni permettono a StickyPrompts di agire sui tuoi sistemi. Tramite l’API puoi creare connessioni e poi usarle direttamente: eseguire SQL su un database, inviare un’email, cercare o aggiornare dati in un CRM e spostare file da e verso Google Drive. Tutto ciò che trovi qui è lo stesso meccanismo che l’app usa quando qualcuno lo richiede in chat.

Tutti i percorsi sono relativi a https://api.stickyprompts.com/api/v1. La chiave agisce come il suo proprietario: valgono le stesse regole di condivisione e di amministrazione dell’app.

Concetti

Provider

:provider nei percorsi e provider nelle risposte usano esattamente queste stringhe:

ProviderFamigliaModalità di connessioneConnessioni
mysql, mariadb, postgres, sqlserverdatabasecredenzialiillimitate
smtp, postmark, resend, sendgridemailcredenzialiuna sola connessione email in totale per proprietario, qualunque sia il provider
pipedriveCRMcredenziali1
activecampaignCRMcredenziali1
brevoCRMcredenziali1
google_drivearchiviazioneOAuth nel browser1, solo personale

I limiti si contano per proprietario: per utente nelle connessioni personali, per workspace in quelle condivise.

Ambito

Ogni connessione è personal (solo il proprietario la vede e la usa) oppure workspace (chiunque nel workspace può usarla). Solo i proprietari e gli amministratori del workspace possono creare, modificare, eliminare una connessione del workspace o leggerne i dettagli salvati; qualsiasi membro può usarla: eseguire query, inviare email tramite la connessione, leggere e, con l’accesso in scrittura, scrivere record nel CRM. Una connessione che non puoi vedere risponde 404, mai 403.

Credenziali o OAuth

  • Le connessioni a database, email e CRM si creano con un’unica chiamata, con le credenziali nel corpo. Il server prima le verifica presso il provider: apre la connessione al database, si autentica sul server SMTP oppure invia un messaggio di prova tramite Postmark, Resend o SendGrid. Un client che usa solo l’API può completare l’intera procedura.
  • Google Drive usa OAuth. La chiamata di connessione restituisce un auth_url; una persona deve aprirlo e approvare la schermata di consenso di Google. Il tuo codice può passare il link a un utente e interrogare GET /integration/connections?provider=google_drive finché la connessione non compare.

Nessun endpoint restituisce mai i segreti.

Stato

Lo status di una connessione vale active, needs_reauth, revoked o error. Qualsiasi route di connessione chiamata su una connessione non attiva risponde 409 {"error":"reconnect_required"}. Oggi solo le connessioni a Google Drive possono uscire dallo stato active; per ripristinarle usa la riconnessione.

Errori

StatoCorpo di esempioSignificato
400"invalid request", "query is required"Input non valido.
403"you do not have permission to manage this connection"Connessione del workspace e non sei né proprietario né amministratore.
403"this connection is read-only; enable write access on the connection to create or edit records"Scrittura nel CRM senza accesso in scrittura.
404"integration is not connected or does not exist"Connessione sconosciuta o non tua.
409"reconnect_required", "connection limit reached for this integration"Serve una nuova autorizzazione, oppure il limite è stato superato.
413"the attachments are too large to send"
422"failed to connect to the integration with the given credentials: ..."Credenziali rifiutate durante la connessione o l’aggiornamento.
422"query is not a single read-only select statement"SQL non consentito al livello di autorizzazione della connessione.
422"the message was rejected: ..."Il provider email ha rifiutato il messaggio.
501"integration provider does not support this capability: ..."Per esempio i deal su un CRM che non li gestisce.
502"failed to send the message: ...", "failed to reach the crm provider: ..."Il provider a monte non ha risposto correttamente.
504"query timed out"La query sul database ha superato il timeout.
500"internal server error"Errori non mappati, compresi gli errori SQL sollevati dal database stesso.

Catalogo e connessioni

GET /integration

GET /api/v1/integration
Autorizzazione integrations_get

Il catalogo dei provider, con le capacità di ciascuno e il numero di connessioni che hai già.

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

max_connections: 0 significa illimitate. Il limite condiviso di una sola connessione email non compare qui.

GET /integration/ssh-tunnel/public-key

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

Le connessioni ai database possono raggiungere un database privato tramite un jump host SSH. Aggiungi questa chiave pubblica al file authorized_keys dell’utente SSH sul tuo jump host e consenti l’indirizzo di StickyPrompts nel firewall.

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

POST /integration/:provider/connect

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

Crea una nuova connessione (non ne sostituisce mai una esistente). Il corpo è un unico oggetto piatto: i campi comuni più quelli specifici del provider.

Campi comuni del corpo
name string obbligatorio
Un nome che le persone riconoscano, per esempio «Northwind Retail DB».
description string facoltativo
Facoltativo.
scope string obbligatorio
personal o workspace. workspace richiede un proprietario o un amministratore del workspace.
database_permission string facoltativo predefinito read_only
Solo per i database: read_only, create_update o full_access. Vedi livelli di autorizzazione.
Campi per i database (mysql, mariadb, postgres, sqlserver)
host string obbligatorio
Il nome host così come lo vede StickyPrompts, oppure come lo vede il jump host se usi SSH.
port integer facoltativo
Predefinita: 3306 (MySQL, MariaDB), 5432 (PostgreSQL), 1433 (SQL Server).
database string obbligatorio
schema string facoltativo
Predefinito per PostgreSQL: public; per SQL Server: dbo.
username string obbligatorio
Usa un utente dedicato con i privilegi minimi necessari per il lavoro.
password string obbligatorio
ssl_mode string facoltativo
PostgreSQL: disable, require (predefinito), verify-ca, verify-full. MySQL/MariaDB: true, false, skip-verify, preferred (predefinito). SQL Server: true (predefinito), skip-verify, false.
ssh_host string facoltativo
Instrada la connessione attraverso questo jump host SSH.
ssh_port integer facoltativo
ssh_username string facoltativo
Obbligatorio con ssh_host.
Campi per l'email (smtp, postmark, resend, sendgrid)
default_from_email string obbligatorio
Il mittente predefinito. Per Postmark, Resend e SendGrid deve essere già un mittente accettato dal tuo provider: il test della connessione invia un vero messaggio di prova.
default_from_name string facoltativo
default_reply_to string facoltativo
server_token string facoltativo
Postmark.
api_key string facoltativo
Resend e SendGrid.
host, port, username, password, encryption various facoltativo
SMTP. encryption vale starttls (predefinito), ssl o none; port è 587 per impostazione predefinita, oppure 465 con ssl.
Campi per i CRM
api_token string facoltativo
Pipedrive (obbligatorio).
api_url, api_key string facoltativo
ActiveCampaign (entrambi obbligatori; api_url è l’URL del tuo account).
api_key string facoltativo
Brevo (obbligatorio).
allow_write boolean facoltativo predefinito false
Senza questo campo la connessione è in sola lettura: l’aggiunta o la modifica di contatti e la creazione di deal rispondono 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}

Risposta 200 {"connection_id": 42}. Per google_drive la risposta è invece 200 {"auth_url": "..."}: indirizza una persona a quell’URL per completare la connessione.

GET /integration/connections

GET /api/v1/integration/connections

Tutte le connessioni che puoi vedere (le tue più quelle condivise del tuo workspace), dalla più recente. Parametro facoltativo ?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 è un’etichetta non riservata: user@host:port/database per i database, il mittente predefinito per l’email, l’URL dell’account per ActiveCampaign. L’accesso in scrittura al CRM non compare in questo elenco; leggilo da GET .../crm/connection.

PATCH /integration/connections/:connectionId

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

Rinomina la connessione, cambia il livello di autorizzazione del database o ruota le credenziali. Invia sempre name (quello attuale se non stai rinominando). description viene sempre scritto, quindi se lo ometti viene svuotato. Cambiano solo i campi del provider che invii; se è presente un qualsiasi campo di credenziali, la configurazione risultante viene verificata di nuovo prima del salvataggio (422 in caso di errore). Per i database, "ssh_host": "" disattiva il tunnel SSH. Restituisce 200 con corpo vuoto.

DELETE /integration/connections/:connectionId

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

Elimina la connessione e le credenziali salvate. Per Google Drive, l’autorizzazione viene prima revocata presso Google. Restituisce 204.

POST /integration/connections/:connectionId/reconnect

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

Avvia un nuovo consenso OAuth per una connessione a Google Drive, mantenendone ID e nome. Restituisce 200 {"auth_url": "..."}. I provider basati su credenziali rispondono 501; per questi usa PATCH.

Database

Livelli di autorizzazione

Il database_permission della connessione stabilisce quali istruzioni SQL accetta l’endpoint di query, a prescindere da ciò che può fare la chiave API:

LivelloConsentito
read_onlyEsattamente un’istruzione SELECT o WITH.
create_updateEsattamente un’istruzione SELECT, WITH, INSERT o UPDATE.
full_accessTutto ciò che l’utente del database può eseguire. Nessun filtro sulle istruzioni.

Con read_only e create_update l’intera istruzione viene analizzata alla ricerca di parole chiave vietate, quindi una query di sola lettura che contiene semplicemente una parola come update nel nome di una colonna o in una stringa viene rifiutata. Per MySQL, MariaDB e PostgreSQL, le sessioni di sola lettura vengono anche aperte in modalità di sola lettura; SQL Server si affida solo al controllo delle parole chiave. In ogni caso, connettiti con un utente del database che abbia soltanto i diritti che intendi concedere.

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

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

Tutte le tabelle e le viste dello schema della connessione, con le relative colonne:

{
  "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

I dettagli di connessione salvati, senza la password. Per le connessioni del workspace, solo per proprietari e amministratori. I campi che hai lasciato vuoti vengono restituiti come 0 o "", anche se per la connessione è stato usato un valore predefinito.

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

POST /api/v1/integration/connections/:connectionId/database/query
Corpo
query string obbligatorio
Una sola istruzione SQL.
row_limit integer facoltativo predefinito 100
Al massimo 1000.
timeout_seconds integer facoltativo predefinito 10
Al massimo 30.
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();

Risposta per una SELECT:

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

truncated: true significa che esistevano altre righe oltre row_limit. Le colonne numeriche arrivano spesso come stringhe. Le altre istruzioni (consentite ai livelli superiori) restituiscono solo row_count, cioè il numero di righe interessate. Gli errori SQL sollevati dal database restituiscono 500 senza il messaggio del database, quindi prova prima le query in un client di database.

Email

La posta parte sempre con le credenziali dell’account collegato; StickyPrompts non fornisce un proprio mittente.

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

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

Le impostazioni del mittente (provider, default_from_email, default_from_name, default_reply_to, più host, porta, nome utente e crittografia per SMTP). Token e password non vengono mai restituiti. Per le connessioni del workspace, solo per proprietari e amministratori.

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

POST /api/v1/integration/connections/:connectionId/email/send
Autorizzazione integration_email_manage Strumento MCP send_email
Corpo
to Address[] obbligatorio
Almeno un {"email": "...", "name": "..."}.
cc, bcc Address[] facoltativo
to, cc e bcc insieme: al massimo 50 destinatari.
reply_to Address[] facoltativo
Per impostazione predefinita, l’indirizzo di risposta della connessione.
subject string obbligatorio
html_body string facoltativo
Invia html_body, text_body o entrambi.
text_body string facoltativo
from_email, from_name string facoltativo
Sostituiscono il mittente per questo messaggio. Il tuo provider potrebbe rifiutare un mittente non verificato.
attachment_file_ids integer[] facoltativo
Fino a 10 file di StickyPrompts di tua proprietà. Limiti di dimensione dopo la codifica: SMTP 25 MB, Postmark 10 MB, SendGrid 30 MB, Resend 40 MB.
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."
  }'

Risposta 200 {"message_id": "<...>", "provider": "postmark"}: l’ID assegnato dal provider, utile per trovare il messaggio nella sua dashboard.

CRM

Le letture funzionano su tutte le connessioni CRM. Le scritture (aggiunta o modifica di contatti e creazione di deal) richiedono allow_write sulla connessione.

Contatto: email (obbligatorio in ogni scrittura e chiave di ricerca per le modifiche), first_name, last_name, phone, company, custom_fields (specifici del provider), list_ids (Brevo, ActiveCampaign) e tag_ids (ActiveCampaign). I risultati vengono restituiti come {"remote_id", "provider", "contact"}.

Deal: title, value, currency, contact_email (deve appartenere a un contatto esistente) e stage (un’etichetta libera). I risultati vengono restituiti come {"remote_id", "provider", "deal"}.

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

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

{"provider": "pipedrive", "allow_write": true} (più api_url per ActiveCampaign).

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

GET /api/v1/integration/connections/:connectionId/crm/contacts
Autorizzazione integration_crm_get Strumento MCP search_crm_contacts

Cerca i contatti con query (obbligatorio) e filtri facoltativi del provider in notazione con parentesi quadre, per esempio ?query=priya&filters[organization_id]=1. Pipedrive e ActiveCampaign eseguono una ricerca a testo libero; Brevo cerca un singolo indirizzo email o ID esatto.

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

GET /api/v1/integration/connections/:connectionId/crm/contacts/list
Autorizzazione integration_crm_get Strumento MCP list_crm_contacts

Sfoglia i contatti. limit (predefinito 50), poi pagina con cursor (Pipedrive: passa il next_cursor precedente) oppure con offset (ActiveCampaign, Brevo). Restituisce {"contacts": [...], "has_more": true, "next_cursor": "..."}.

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

POST /api/v1/integration/connections/:connectionId/crm/contacts
Autorizzazione integration_crm_manage Strumento MCP add_crm_contact

Aggiunge un contatto. Ne crea sempre uno nuovo, anche se l’indirizzo email esiste già: cerca prima.

{ "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
Autorizzazione integration_crm_manage Strumento MCP edit_crm_contact

Modifica il contatto con quell’email; cambiano solo i campi che invii (invia "" per svuotarne uno). Non crea mai contatti: 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
Autorizzazione integration_crm_get Strumento MCP search_crm_deals

Cerca i deal per titolo o per indirizzo email del contatto collegato con query, più i filtri del provider (per Pipedrive: status, person_id, organization_id, exact_match).

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

GET /api/v1/integration/connections/:connectionId/crm/deals/list
Autorizzazione integration_crm_get Strumento MCP list_crm_deals

Sfoglia i deal, con la stessa paginazione dei contatti. I filtri di Pipedrive includono stage_id, status, owner_id e pipeline_id.

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

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

404 se nessun contatto ha quell’indirizzo email.

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

GET /api/v1/integration/connections/:connectionId/crm/lists
Autorizzazione integration_crm_get Strumento MCP list_crm_lists

Liste (Brevo, ActiveCampaign) e tag (ActiveCampaign) nella forma [{"id": "12", "name": "Newsletter"}], da usare nei filtri e in list_ids / tag_ids di un contatto. Gli altri provider rispondono 501.

Google Drive

Le route di archiviazione agiscono sempre sulla tua connessione personale a Drive e richiedono il provider nel percorso: /integration/google_drive/storage/.... Gli ID di cartelle ed elementi sono root oppure ID di Drive.

GET /integration/:provider/storage/entries

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

Elenca il contenuto di una cartella: folder_id (predefinito root), page_token, page_size (da 1 a 200, predefinito 100), kind (folder o file). Restituisce {"entries": [...], "next_page_token": "", "breadcrumbs": [...]}. Ogni elemento ha id, name, kind, mime_type, size, modified_at, web_url, importable e import_name (Documenti e Disegni vengono importati come PDF, Fogli come XLSX, Presentazioni come PPTX).

GET /integration/:provider/storage/search

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

query (obbligatorio) più la stessa paginazione e gli stessi filtri.

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

Copia da 1 a 20 elementi di Drive (entry_ids) in StickyPrompts come normali file, eventualmente collegati a un project_id. Ogni elemento riesce o fallisce indipendentemente dagli altri, quindi controlla sempre failed: {"files": [...], "failed": [{"entry_id": "...", "error": "..."}]}. Fino a 100 MB per file.

POST /integration/:provider/storage/export

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

Copia un file di StickyPrompts di tua proprietà (file_id) in una cartella di Drive (folder_id, è ammesso root), eventualmente rinominandolo con name.