# FlutterFlow

FlutterFlow compile en une application que tient ton utilisateur, donc la question n’est pas quels champs remplir, mais où se retrouve la clé. La requête ci‑dessous a été envoyée en production exactement dans la forme que compose l’appel ; les étapes dans FlutterFlow sont écrites selon la documentation FlutterFlow en date du 2026‑09‑17.

Commence par créer une clé, comme décrit dans la section [Clé pour l’automatisation](/integrations/#ключ-для-автоматизації), avec le scope `chart`.

<Aside type="caution" title="Ключ у звичайному виклику їде разом із застосунком">
Un appel qui n’est pas marqué comme privé s’exécute depuis l’appareil, et son en‑tête se trouve à l’intérieur du bundle compilé pour iOS, Android et le web, où il peut être lu par n’importe qui. Rends l’appel **privé** : alors FlutterFlow le fait passer par Firebase Cloud Function, et la clé reste sur le serveur. La vérification maison de FlutterFlow consiste à télécharger le code du projet et à chercher la clé dans les fichiers front‑end, et elle n’est disponible que sur le forfait payant.
</Aside>

## 1. Crée l’appel

Ouvre **API Calls**, clique sur **+ Add**, sélectionne **Create API Call** et remplis :

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

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

- Onglet **Headers**, **+ Add Header** : une ligne `X-Api-Key: ` suivie de ta clé. Une deuxième ligne `Content-Type: application/json`.
- Onglet **Variables** : cinq variables de type String, `date`, `time`, `timezone`, `latitude`, `longitude`, chacune avec une valeur par défaut tirée du JSON ci‑dessous.
- Onglet **Body**, dans la liste déroulante **JSON** : colle le JSON et glisse‑y les variables.

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

Latitude et longitude restent des chaînes volontairement : l’API accepte `"50.45"` comme nombre, mais la chaîne simplifie le glisser‑déposer des variables.

Clique sur **Add Call**, ouvre **Response & Test**, clique sur **Test API Call** et regarde la réponse dans **Test Response**. `data.input.timezoneOffset` revient comme `4` : c’est exactement le décalage de Kyiv à cette date.

## 2. Rends l’appel privé

Dans **Advanced Settings** de l’appel, active **Make Private**, clique sur **Save**, puis sur **Deploy APIs**. Maintenant l’appel s’exécute dans Firebase Cloud Function, donc le projet a besoin d’un Firebase connecté et d’un forfait Firebase avec Cloud Functions.

<Aside type="caution" title="Приватні виклики не успадковують заголовки групи">
Si tu places la clé sur le **API Group**, et non sur l’appel lui‑même, FlutterFlow cessera de l’envoyer dès que l’appel devient privé : les en‑têtes du groupe ne sont pas hérités par les appels privés. Ajoute `X-Api-Key` sur l’appel lui‑même, sinon le premier lancement privé renverra `401`.
</Aside>

Deux autres points que la documentation FlutterFlow indique clairement : la clé transmise depuis le front‑end, par exemple via remote config, reste exposée même dans un appel privé, et la forme sécurisée est l’en‑tête intégré directement dans l’appel.

## 3. Lis la réponse

Dans **JSON Paths**, clique sur **+ Add JSON Path** et donne un nom à chacun :

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

Le signe est la longitude divisée par 30 et arrondie à l’inférieur, comme un indice dans une liste de douze noms : par exemple l’Ascendant `159.26` donne `5`, c’est‑à‑dire Vierge. Une fonction personnalisée de quatre lignes ou une liste de douze lignes et l’indice suffisent.

## La build web ne peut pas nous appeler depuis le navigateur

Mesuré le 2026‑09‑17 depuis une page sur un domaine tiers : `POST /v1/chart` répond au preflight sans l’en‑tête `access-control-allow-origin`, et Chrome bloque la requête. Le navigateur sur un domaine étranger ne reçoit que `/v1/public/*` et `/v1/embed/*`.

FlutterFlow fait passer les appels via son propre proxy dans le constructeur, en Run mode et Test mode, donc un appel qui fonctionne là‑bas peut échouer après la publication de l’application web. Deux solutions, et la première est recommandée :

- **Rends l’appel privé**, comme ci‑dessus. Alors il s’exécute dans Cloud Function, pas dans le navigateur, et cela résout immédiatement le problème de la clé et le problème CORS.
- **Mets ton propre backend devant nous**, si tu en as déjà un. La configuration du proxy dans FlutterFlow, avec ton propre proxy URL, est documentée pour le constructeur et les modes Run et Test ; la documentation ne dit rien sur la build web publiée, donc il ne faut pas compter sur eux.

La clé publique `pk_` ne résout pas cela : elle ne récupère que `/v1/public/*` et `/v1/embed/*`, et les builds pour iOS et Android la rejettent complètement, car ils n’envoient pas de web‑origin.

## Erreurs

- **`401`** sur un appel privé : la clé est sur le groupe, pas sur l’appel.
- **`400 INVALID_FIELD` avec `timezone` dans `details`** : le fuseau est vide, c’est une abréviation comme `EST` ou pas un nom de zone.
- **`400` avec `date` ou `time` dans `details`** : le format n’est pas `YYYY-MM-DD` / `HH:MM:SS`.
- **`403 ENDPOINT_NOT_IN_SCOPE`** : le scope de la clé ne contient pas `chart`.
- **`429 KEY_BUDGET_EXHAUSTED`** : la clé a épuisé son budget ; augmente‑le dans le tableau de bord.

<Aside type="note">
Le forfait gratuit de FlutterFlow autorise deux API‑endpoints par projet et ne propose pas d’import OpenAPI, donc l’appel doit être ajouté manuellement, laissant un slot supplémentaire. L’API ne géocode pas : les coordonnées proviennent de tes propres champs ou d’un service de géocodage pour lequel tu possèdes une clé.
</Aside>
