API del sito
Con l’API del sito il sito della radio prende dal pannello programmi, palinsesto (con le variazioni) e speaker, senza ricopiarli a mano. È pensata per i siti statici (Astro, Next.js, Hugo, Eleventy…) che leggono i dati al momento della build, sul server: la chiave non deve mai arrivare al browser.
Creare la chiave
Sezione intitolata “Creare la chiave”La chiave la crea la direzione della radio (Station Manager, Direttore, Editore).
- Nel pannello apri Palinsesto → Impostazioni e trova il riquadro Sito della radio.
- Premi Crea la chiave. La chiave si vede una volta sola: copiala subito.
- Mettila nelle variabili d’ambiente del sito (es.
RADIOPANEL_API_KEY), mai nel codice delle pagine.
Nello stesso riquadro trovi l’Indirizzo dell’API, le ultime cifre della chiave attiva, Crea una nuova chiave (quella vecchia smette subito di funzionare) e Revoca. Senza chiave i dati non escono dal pannello. La chiave identifica anche la radio: non serve indicarla nella richiesta.
La richiesta
Sezione intitolata “La richiesta”GET https://pannello.example.it/public/sito/api.php?risorsa=tuttoX-Api-Key: rps_la-tua-chiaveLa chiave comincia sempre con rps_.
- La chiave va nell’intestazione
X-Api-Key, oppure inAuthorization: Bearer <chiave>. - Sono accettati solo
GETeHEAD. - L’API non risponde ai browser di altri siti (nessuna intestazione CORS): chiamala dal server o dallo script di build.
// src/lib/radiopanel.js - letto una volta durante la buildconst API = 'https://pannello.example.it/public/sito/api.php';
export async function datiRadio() { const res = await fetch(`${API}?risorsa=tutto`, { headers: { 'X-Api-Key': import.meta.env.RADIOPANEL_API_KEY }, }); if (!res.ok) throw new Error(`RadioPanel: errore ${res.status}`); return res.json();}const res = await fetch('https://pannello.example.it/public/sito/api.php?risorsa=programmi', { headers: { Authorization: `Bearer ${process.env.RADIOPANEL_API_KEY}` },});const { programmi } = await res.json();curl -H "X-Api-Key: $RADIOPANEL_API_KEY" \ "https://pannello.example.it/public/sito/api.php?risorsa=palinsesto"Risorse
Sezione intitolata “Risorse”Il parametro risorsa sceglie cosa leggere:
risorsa |
Contenuto |
|---|---|
tutto (predefinito) |
radio, programmi, speaker, palinsesto e adesso in una sola risposta. Una build di solito fa solo questa chiamata. |
radio |
I dati della radio. |
programmi |
I programmi non archiviati. |
speaker |
Le persone con il profilo pubblico attivo. |
palinsesto |
Settimana tipo e prossimi 7 giorni con le variazioni. |
adesso |
Programma in onda, prossimo e brano, al momento della chiamata. |
Ogni risposta riuscita ha success, la versione del formato (oggi 1) e generato (data e ora della risposta, ISO 8601), più le chiavi della risorsa chiesta.
| Codice | Quando |
|---|---|
401 |
Chiave mancante o non valida (anche se la radio è disabilitata). |
404 |
risorsa non valida. |
405 |
Metodo diverso da GET/HEAD. |
429 |
Troppe chiavi sbagliate dallo stesso indirizzo: aspetta i secondi indicati in Retry-After. |
500 |
Errore interno: riprova tra qualche minuto. |
Gli errori rispondono con { "success": false, "message": "…" }.
La risposta
Sezione intitolata “La risposta”Esempio abbreviato di ?risorsa=tutto:
{ "success": true, "versione": 1, "generato": "2026-11-14T10:00:00+01:00", "radio": { "nome": "Radio Esempio", "nome_breve": "RE", "codename": "radioesempio", "sito": "https://www.radioesempio.it", "streaming": "https://stream.radioesempio.it/live", "nowplaying": "https://azuracast.radioesempio.it/api/nowplaying/1", "whatsapp": "+39 333 1234567", "fuso_orario": "Europe/Rome", "richieste": "https://pannello.example.it/public/rpigroup/request_radioesempio", "statistiche": { "script": "https://pannello.example.it/public/sito/statistiche.js", "radio": "radioesempio", "codice": "<script defer src=\"https://pannello.example.it/public/sito/statistiche.js\" data-radio=\"radioesempio\"></script>" } }, "programmi": [ { "id": 12, "slug": "buongiorno-radio", "titolo": "Buongiorno Radio", "sottotitolo": "La sveglia della città", "immagine": "https://pannello.example.it/public/sito/immagine?f=…", "descrizione_html": "<p>Notizie, musica e ospiti.</p>", "descrizione_testo": "Notizie, musica e ospiti.", "conduttori": [ { "nome": "Mario Rossi", "speaker": "mario-rossi" }, { "nome": "Luca", "speaker": null } ] } ], "speaker": [ { "id": 7, "slug": "mario-rossi", "nome": "Mario Rossi", "ruolo": "Conduttore del mattino", "ruolo_pubblico": "Conduttore del mattino", "ruolo_base": "Speaker", "ruolo_preciso": "", "bio": "In radio dal 2010.", "immagine": "https://pannello.example.it/public/sito/immagine?f=…", "social": { "instagram": "https://www.instagram.com/mario.rossi" }, "programmi": ["buongiorno-radio"] } ], "palinsesto": { "settimana": [ { "giorno": 1, "giorno_nome": "Lunedì", "inizio": "07:00", "fine": "09:00", "titolo": "Buongiorno Radio", "programma": "buongiorno-radio", "speaker": { "nome": "Mario Rossi", "speaker": "mario-rossi" } } ], "prossimi_giorni": [ { "giorno": 1, "giorno_nome": "Lunedì", "inizio": "07:00", "fine": "09:00", "titolo": "Buongiorno Radio", "programma": "buongiorno-radio", "speaker": { "nome": "Mario Rossi", "speaker": "mario-rossi" }, "data": "2026-11-16", "inizio_iso": "2026-11-16T07:00:00+01:00", "fine_iso": "2026-11-16T09:00:00+01:00", "variazione": false } ] }, "adesso": { "in_onda": { "titolo": "Buongiorno Radio", "programma": "buongiorno-radio", "speaker": { "nome": "Mario Rossi", "speaker": "mario-rossi" }, "inizio_iso": "2026-11-14T07:00:00+01:00", "fine_iso": "2026-11-14T09:00:00+01:00" }, "prossimo": null, "brano": { "titolo": "Titolo", "artista": "Artista", "testo": "Artista - Titolo" }, "online": true }}| Campo | Contenuto |
|---|---|
nome, nome_breve, codename |
Nome completo, nome breve e codice della radio. |
sito, streaming, whatsapp |
Sito web, indirizzo dello streaming e numero WhatsApp, come in Gestisci Radio (stringa vuota se mancano). |
nowplaying |
Indirizzo pubblico del “now playing” di AzuraCast: il sito lo può leggere dal browser per il brano in onda. Vuoto se la radio non lo ha. |
fuso_orario |
Fuso orario di orari e date (es. Europe/Rome). |
richieste |
Indirizzo del modulo delle richieste della radio (vedi sotto); vuoto se la radio non ne ha uno. |
statistiche |
Script delle analitiche del sito: script, radio e il codice pronto. null se la radio non ha il Sito web impostato o le analitiche sono spente. |
programmi
Sezione intitolata “programmi”Programmi non archiviati, in ordine di nome.
| Campo | Contenuto |
|---|---|
id, slug |
Numero e nome per gli indirizzi del sito (es. buongiorno-radio), unico nella radio. |
titolo, sottotitolo |
Nome e sottotitolo del programma. |
immagine |
Copertina (sempre https://), oppure null. |
descrizione_html |
Descrizione con la formattazione, già ripulita. |
descrizione_testo |
La stessa descrizione in testo semplice (anteprime, meta description). |
conduttori |
Elenco di { nome, speaker }: speaker è lo slug della persona se ha il profilo pubblico, altrimenti null. |
speaker
Sezione intitolata “speaker”Solo le persone con il profilo pubblico attivo (scelto da loro in Modifica Profilo o dalla direzione), in ordine di nome. Email, username, telefono e gli altri dati dell’account non escono mai; delle persone senza profilo pubblico esce solo il nome, nei programmi e nel palinsesto.
| Campo | Contenuto |
|---|---|
id, slug |
Numero e nome per gli indirizzi del sito. |
nome |
Il nome pubblico (es. nome d’arte) o, se manca, il nome. |
ruolo |
Il ruolo da mostrare: il ruolo pubblico, altrimenti il ruolo preciso, altrimenti il ruolo nel pannello. Usa questo. |
ruolo_pubblico, ruolo_preciso, ruolo_base |
I tre ruoli separati, per i siti che li usano già. |
bio |
Biografia in testo semplice (al massimo 1000 caratteri). |
immagine |
Immagine profilo, oppure null. |
social |
Oggetto con instagram e/o tiktok (indirizzi completi), solo se la persona ha scelto di mostrarli; altrimenti vuoto. |
programmi |
Gli slug dei programmi che conduce. |
palinsesto
Sezione intitolata “palinsesto”settimana: la settimana tipo.giornova da 1 (lunedì) a 7 (domenica),inizioefinesono oreHH:00,titoloè il nome del blocco eprogrammaloslugdel programma corrispondente (onull),speakerè{ nome, speaker }onull.prossimi_giorni: i prossimi 7 giorni da oggi, con le stesse chiavi piùdata(AAAA-MM-GG),inizio_isoefine_iso(ISO 8601 nel fuso della radio) evariazione(truese la puntata è cambiata solo per quel giorno: speciali, sostituzioni, scambi di turno).
in_onda e prossimo (titolo, programma, speaker, inizio_iso, fine_iso, oppure null), brano (titolo, artista, testo, oppure null) e online (stato dello streaming, null se non noto). Sono i dati al momento della chiamata: in un sito statico invecchiano subito. Per il “in onda adesso” calcola il programma dal browser con prossimi_giorni e leggi il brano da radio.nowplaying.
Immagini
Sezione intitolata “Immagini”Gli indirizzi in immagine si usano direttamente nelle pagine del sito, senza chiave. Il nome del file cambia a ogni nuovo caricamento, quindi le immagini si possono tenere in cache per sempre (anche su una CDN). Se una persona disattiva il profilo pubblico o un programma viene archiviato, l’immagine smette di essere servita.
Aggiornare il sito da solo
Sezione intitolata “Aggiornare il sito da solo”Un sito statico mostra i dati dell’ultima build. Con un deploy hook il pannello ricostruisce il sito da solo quando cambiano programmi, palinsesto, variazioni o profili pubblici.
- Crea il deploy hook nel servizio che ospita il sito. In Cloudflare Pages: progetto del sito → Settings → Builds → Deploy hooks → Add deploy hook.
- Nel pannello, in Palinsesto → Impostazioni → Aggiornamento automatico del sito, incolla l’indirizzo (deve essere
https://) e premi Attiva l’aggiornamento automatico.
Il pannello chiama il deploy hook con una richiesta POST senza corpo:
- quando i dati pubblicati cambiano, al massimo una volta ogni 5 minuti (più modifiche ravvicinate finiscono nella stessa ricostruzione);
- comunque una volta al giorno, perché a mezzanotte cambiano le date dei prossimi 7 giorni;
- subito, con Aggiorna ora il sito (al massimo una volta al minuto).
Nel riquadro vedi l’ultimo aggiornamento e il suo esito. Togli disattiva l’aggiornamento automatico. L’indirizzo del deploy hook viene salvato cifrato.
Inviare un messaggio alla regia
Sezione intitolata “Inviare un messaggio alla regia”Dal sito gli ascoltatori possono scrivere alla regia: i messaggi arrivano nelle Richieste del pannello, come quelli del modulo pubblico, con gli stessi limiti contro gli invii ripetuti. L’indirizzo è in radio.richieste.
Questa chiamata parte dal browser dell’ascoltatore e non usa la chiave API:
// richieste: valore di radio.richieste letto durante la buildasync function scriviAllaRegia(richieste, nome, messaggio) { const dati = new FormData(); dati.append('ajax_request', '1'); dati.append('author', nome); // facoltativo, al massimo 100 caratteri dati.append('message', messaggio); // obbligatorio, al massimo 500 caratteri const res = await fetch(richieste, { method: 'POST', body: dati }); return res.json(); // { "success": true } oppure { "success": false, "error": "…" }}Mostra all’ascoltatore il testo di error quando success è false: ad esempio quando chiede di aspettare prima di inviare un altro messaggio.
