Prova la demo

API per sviluppatori

Collega Social Studio al tuo gestionale, a Zapier, Make, n8n o Google Looker Studio. JSON, errori in italiano, inclusa dal piano Pro.

Come si usa

Indirizzo base: https://www.citygraphnapoli.it/social-studio/api/v1. Crea la chiave in API e webhook nell'area di lavoro e mandala in ogni richiesta:

curl -H "Authorization: Bearer ss_la_tua_chiave" https://www.citygraphnapoli.it/social-studio/api/v1/brands

Il brand si indica con lo slug (per esempio pizzeria-fiordilatte) o con il numero. Date in ora italiana, formato AAAA-MM-GG HH:MM.

Endpoint

GET/stato

Versione del servizio e canali collegati per ogni brand.

Risposta

{"ok":true,"versione":"1.0.0","account":"Agenzia Esempio","piano":"Agenzia","brand":[{"id":3,"slug":"pizzeria-esempio","nome":"Pizzeria Esempio","canali":[{"canale":"facebook","nome":"Pizzeria Esempio","stato":"collegato","modalita":"diretta","pubblica_da_solo":true,"ultimo_errore":null}]}]}

GET/brands

Elenco dei brand dell'account con i loro canali.

Risposta

{"ok":true,"brand":[{"id":3,"slug":"pizzeria-esempio","nome":"Pizzeria Esempio","settore":"servizi","citta":"Napoli","colore":"#0b7a75","sito":"https://www.esempio.it","canali":[]}]}

GET/posts?brand=&dal=&al=&stato=&limite=

Post (tutti i brand o uno). Date AAAA-MM-GG; stato: bozza, da_approvare, programmato, pubblicato, parziale, errore, a_mano; limite massimo 500.

Risposta

{"ok":true,"totale":1,"post":[{"id":41,"brand":"pizzeria-esempio","stato":"programmato","data":"2026-10-21 12:30:00","testo":"…","canali":[{"canale":"instagram","formato":"feed","stato":"in_attesa","url":""}]}]}

GET/posts/{id}

Un post con lo stato per canale e i numeri letti dalle piattaforme.

POST/posts

Crea un post. Con "stato":"pubblicato" REGISTRA un post già uscito altrove (per esempio da Fily AI): serve "canale", facoltativi "url_esterno" e "data". Idempotente su "id_esterno": se esiste già risponde 200 con "gia_presente":true.

Corpo (JSON)

{"brand":"pizzeria-esempio","testo":"Nuova pizza del giorno…","stato":"programmato","data":"2026-10-22 18:00","canali":["facebook","instagram"],"link":"https://www.esempio.it","primo_commento":"#napoli","media":["https://www.esempio.it/foto.jpg"],"fonte":"fily-ai","id_esterno":"fily-123"}

Risposta

{"ok":true,"gia_presente":false,"post":{"id":42,"stato":"programmato"}}

POST/posts (già pubblicato)

Esempio di registrazione di un post uscito su Facebook da un altro programma.

Corpo (JSON)

{"brand":"pizzeria-esempio","stato":"pubblicato","canale":"facebook","testo":"…","data":"2026-10-19 10:05","url_esterno":"https://www.facebook.com/pizzeriaesempio/posts/123","fonte":"fily-ai","id_esterno":"fily-fb-778"}

DELETE/posts/{id}

Cancella un post non ancora uscito.

Risposta

{"ok":true,"cancellato":42}

GET/analytics/riepilogo?brand=&giorni=30

Follower, variazione, copertura, interazioni, visualizzazioni, post e clic del periodo, per canale e in totale, con i post migliori (giorni da 1 a 730; piano Free: massimo 30).

Risposta

{"ok":true,"brand":"pizzeria-esempio","dal":"2026-09-20","al":"2026-10-19","totale":{"follower":13555,"variazione_follower":846,"copertura":57329,"interazioni":3430,"visualizzazioni":80861,"post":44,"clic":1173,"tasso_interazione":5.98},"canali":[{"canale":"instagram","follower":5120,"variazione_follower":310,"copertura":…,"post_migliori":[{"url":"…","testo":"…","interazioni":212}]}],"post_migliori":[]}

GET/analytics/serie?brand=&metrica=&dal=&al=&canale=

Serie giornaliera di una metrica: followers, reach, impressions, engagement, views, clicks, posts.

Risposta

{"ok":true,"metrica":"engagement","serie":[{"giorno":"2026-10-18","valore":121}]}

GET/inbox/conteggio?brand=

Quanti commenti e messaggi ci sono per stato.

Risposta

{"ok":true,"brand":"pizzeria-esempio","da_fare":4,"letto":2,"fatto":31,"nascosto":1,"totale":38}

GET/inbox?brand=&stato=da-fare&limite=50

Commenti, messaggi e menzioni (stato: da-fare, letto, fatto, nascosto, tutti), con il link per aprirli nell'area di lavoro.

Risposta

{"ok":true,"elementi":[{"id":7,"canale":"instagram","tipo":"commento","autore":"@cliente","testo":"Siete aperti lunedì?","stato":"da_fare","link_app":"…"}]}

GET/report?brand=&mese=AAAA-MM

Link firmati al report PDF e PowerPoint del mese (se non c'è lo crea; ai=0 per il commento a regole, rigenera=1 per rifarlo).

Risposta

{"ok":true,"mese":"2026-09","pdf":"https://…/r.php?id=…","pptx":"https://…","commento":"…"}

GET/profili?brand=

Stato dei profili social (tutti i brand o uno): canale, stato, pagina collegata, fonte del collegamento, ultimo errore, ultima lettura e ultimi follower letti. Il token non viene MAI restituito.

Risposta

{"ok":true,"totale":2,"profili":[{"brand":"pizzeria-esempio","canale":"facebook","stato":"collegato","modalita":"diretta","id_esterno":"102938475610","nome":"Pizzeria Esempio","fonte":"fily-ai","scade_il":null,"ultimo_errore":null,"ultima_lettura":"2026-10-20 09:05:00","follower":1520,"follower_del":"2026-10-20"}]}

POST/profili

SOLO account interno CGFA. Collega (o aggiorna) un profilo con un token già ottenuto altrove (Fily AI): network facebook, instagram, threads o telegram; id_esterno = ID della Pagina, ID utente Instagram/Threads oppure @canale / -100… per Telegram. Il token si salva cifrato e non si rilegge più. Idempotente ("esito": collegato 201, aggiornato o invariato 200). Fa subito una lettura di prova (nome della pagina): se non riesce lo scrive in "ultimo_errore" (token rifiutato = stato "scaduto"). 409 se il brand ha già quel canale collegato a mano a un'altra pagina.

Corpo (JSON)

{"brand":"pizzeria-esempio","network":"facebook","id_esterno":"102938475610","nome":"Pizzeria Esempio","handle":"","token":"EAAB…","scade_il":null,"fonte":"fily-ai"}

Risposta

{"ok":true,"esito":"collegato","lettura_di_prova":{"ok":true,"nome":"Pizzeria Esempio"},"profilo":{"brand":"pizzeria-esempio","canale":"facebook","stato":"collegato","fonte":"fily-ai"}}

GET/export?tipo=metriche|post|sito|ads&brand=&dal=&al=&formato=csv|json

Esportazione per fogli di calcolo e Google Looker Studio. Solo qui la chiave si può passare anche come ?key= (Google Sheets non manda intestazioni).

Risposta

brand,canale,giorno,follower,copertura,…

GET/webhooks

Webhook dell'account ed eventi disponibili.

POST/webhooks

Aggiunge un webhook in uscita (solo https). Restituisce il segreto per verificare la firma X-SocialStudio-Signature: sha256=HMAC(corpo).

Corpo (JSON)

{"url":"https://hooks.zapier.com/…","eventi":["post.pubblicato","report.pronto"]}

Risposta

{"ok":true,"id":3,"segreto":"…"}

DELETE/webhooks/{id}

Elimina un webhook.

Risposta

{"ok":true}

Webhook in uscita

Eventi: post.programmato, post.pubblicato, post.errore, post.approvato, post.modifiche, inbox.nuovo, report.pronto. Ogni invio è un POST JSON {"evento","quando","dati"} con l'intestazione X-SocialStudio-Signature: sha256=… (HMAC SHA-256 del corpo col segreto del webhook). Tre tentativi, poi "fallito".

Google Looker Studio

In un foglio Google scrivi =IMPORTDATA("https://www.citygraphnapoli.it/social-studio/api/v1/export?tipo=metriche&brand=TUO-BRAND&key=TUA-CHIAVE"), poi in Looker Studio aggiungi il foglio come origine dati. Gratis, si aggiorna da solo.

Errori

Risposta d'errore: {"ok":false,"errore":"messaggio in italiano"}.

Novità in Social Studio

Novità della versione 1.1.0