# FlutterFlow

FlutterFlow viene compilato in un'applicazione che resta nelle mani del tuo utente, quindi la questione non è quali campi compilare, ma dove finisce la chiave. La richiesta qui sotto è stata inviata in produzione esattamente nella forma in cui la costruisce la chiamata; i passaggi in FlutterFlow sono scritti secondo la documentazione di FlutterFlow al 2026-09-17.

Prima crea una chiave, come descritto nella sezione [Chiave per l'automazione](/integrations/#ключ-для-автоматизації), con l'ambito `chart`.

<Aside type="caution" title="Chiave in una chiamata normale viaggia con l'applicazione">
Una chiamata non contrassegnata come privata viene eseguita dal dispositivo, e il suo header è all'interno del bundle compilato per iOS, Android e web, dove può essere letto da chiunque. Rendi la chiamata **privata**: allora FlutterFlow la instrada attraverso Firebase Cloud Function, e la chiave rimane sul server. Un controllo personalizzato di FlutterFlow consiste nel scaricare il codice del progetto e cercare la chiave nei file frontend, ed è disponibile solo con il piano a pagamento.
</Aside>

## 1. Crea la chiamata

Apri **API Calls**, clicca **+ Add**, seleziona **Create API Call** e compila:

- **API Call Name**: `Natal chart`.
- **Method Type**: `POST`.
- **URL**:

  ```
  https://api.astroway.info/v1/chart
  ```

- Scheda **Headers**, **+ Add Header**: una riga `X-Api-Key: ` seguita dalla tua chiave. Un'altra riga `Content-Type: application/json`.
- Scheda **Variables**: cinque variabili di tipo String, `date`, `time`, `timezone`, `latitude`, `longitude`, ognuna con un valore predefinito dal JSON qui sotto.
- Scheda **Body**, nel menu a discesa **JSON**: incolla il JSON e trascina le variabili al suo interno.

```json
{
  "date": "1990-05-15",
  "time": "14:30:00",
  "timezone": "Europe/Kyiv",
  "latitude": "50.45",
  "longitude": "30.52"
}
```

Latitudine e longitudine rimangono stringhe intenzionalmente: l'API accetta `"50.45"` come numero, ma la stringa semplifica il trascinamento delle variabili.

Clicca **Add Call**, apri **Response & Test**, premi **Test API Call** e guarda la risposta in **Test Response**. `data.input.timezoneOffset` viene restituito come `4`: è proprio questo lo spostamento di Kiev per quella data.

## 2. Rendi la chiamata privata

Nelle **Advanced Settings** della chiamata attiva **Make Private**, clicca **Save**, poi **Deploy APIs**. Ora la chiamata viene eseguita in Firebase Cloud Function, quindi il progetto necessita di Firebase collegato e di un piano Firebase con Cloud Functions.

<Aside type="caution" title="Le chiamate private non ereditano gli header del gruppo">
Se posizioni la chiave sul **API Group** anziché sulla singola chiamata, FlutterFlow smetterà di inviarla non appena la chiamata diventa privata: gli header del gruppo non vengono ereditati dalle chiamate private. Aggiungi `X-Api-Key` alla chiamata stessa, altrimenti il primo avvio privato restituirà `401`.
</Aside>

Altre due cose che la documentazione di FlutterFlow specifica chiaramente: la chiave inviata dal frontend, ad esempio tramite remote config, rimane esposta anche in una chiamata privata, e la forma sicura è l'header inserito direttamente nella chiamata.

## 3. Leggi la risposta

In **JSON Paths** clicca **+ Add JSON Path** e assegna un nome a ciascuno:

| Nome | JSON Path |
|---|---|
| `ascendant` | `$.data.houses.ascendant` |
| `sunLongitude` | `$.data.planets[0].longitude` |
| `moonLongitude` | `$.data.planets[1].longitude` |
| `offsetUsed` | `$.data.input.timezoneOffset` |

Il segno è la longitudine divisa per 30 e arrotondata per difetto, come indice in una lista di dodici nomi: per esempio l'Ascendente `159.26` dà `5`, cioè Vergine. Basta una funzione personalizzata di quattro righe o una lista di dodici righe e l'indice.

## La build web non può contattarci dal browser

Misurato il 2026-09-17 da una pagina su dominio esterno: `POST /v1/chart` risponde al preflight senza l'header `access-control-allow-origin`, e Chrome blocca la richiesta. Al browser su dominio esterno rispondono solo `/v1/public/*` e `/v1/embed/*`.

FlutterFlow instrada le chiamate attraverso un proxy interno nel builder, in Run mode e Test mode, quindi una chiamata che funziona lì può fallire dopo la pubblicazione dell'app web. Ci sono due soluzioni, e la prima la consigliamo:

- **Rendi la chiamata privata**, come sopra. Così viene eseguita in Cloud Function, non nel browser, e questo risolve subito sia il problema della chiave sia quello del CORS.
- **Metti un tuo backend**, se ne hai già uno. La configurazione del proxy in FlutterFlow, insieme al tuo proxy URL, è documentata per il builder e per le modalità Run e Test; la documentazione non dice nulla sulla build web pubblicata, quindi non è consigliabile fare affidamento su di essa.

Una chiave pubblica `pk_` non risolve questo: accede solo a `/v1/public/*` e `/v1/embed/*`, e dalle build per iOS e Android viene rifiutata del tutto, poiché non inviano il web-origin.

## Errori

- **`401`** su chiamata privata: la chiave è sul gruppo, non sulla chiamata.
- **`400 INVALID_FIELD` con `timezone` in `details`**: zona vuota, è un'abbreviazione tipo `EST` o non è un nome di zona.
- **`400` con `date` o `time` in `details`**: formato non `YYYY-MM-DD` / `HH:MM:SS`.
- **`403 ENDPOINT_NOT_IN_SCOPE`**: nell'ambito della chiave manca `chart`.
- **`429 KEY_BUDGET_EXHAUSTED`**: la chiave ha esaurito il proprio budget; aumentala nella dashboard.

<Aside type="note">
Il piano gratuito di FlutterFlow consente due API-endpoint per progetto e non supporta l'import di OpenAPI, quindi la chiamata deve essere aggiunta manualmente, lasciando ancora uno slot disponibile. L'API non esegue il geocoding: le coordinate provengono dai tuoi campi o da un servizio di geocoding per il quale possiedi una chiave.
</Aside>
