# FlutterFlow

FlutterFlow compilează o aplicație pe care utilizatorul tău o ține în mână, așa că întrebarea nu este ce câmpuri să completezi, ci unde va ajunge cheia. Cererea de mai jos este trimisă în producție exact așa cum este construită de apel; pașii din FlutterFlow sunt scriși conform documentației FlutterFlow la data de 2026-09-17.

Mai întâi, creează o cheie, așa cum este descris în secțiunea [Cheie pentru automatizare](/integrations/#ключ-для-автоматизації), cu domeniul de aplicare `chart`.

<Aside type="caution" title="Cheia într-un apel obișnuit călătorește cu aplicația">
Un apel care nu este marcat ca privat este executat de pe dispozitiv, iar antetul său se află în interiorul build-ului compilat pentru iOS, Android și web, unde poate fi citit de oricine. Fă apelul **privat**: atunci FlutterFlow îl va rula printr-o Firebase Cloud Function, iar cheia va rămâne pe server. Verificarea proprie a FlutterFlow este să descarci codul proiectului și să cauți cheia în fișierele frontend, dar aceasta este disponibilă doar pe un plan plătit.
</Aside>

## 1. Creează apelul

Deschide **API Calls**, apasă **+ Add**, selectează **Create API Call** și completează:

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

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

- Tab-ul **Headers**, **+ Add Header**: un rând `X-Api-Key: ` și apoi cheia ta. Al doilea rând `Content-Type: application/json`.
- Tab-ul **Variables**: cinci variabile de tip String, `date`, `time`, `timezone`, `latitude`, `longitude`, fiecare cu o valoare tipică din JSON-ul de mai jos.
- Tab-ul **Body**, în lista derulantă **JSON**: inserează JSON-ul și trage variabilele în el.

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

Latitudinea și longitudinea rămân șiruri de caractere intenționat: API-ul acceptă `"50.45"` ca număr, iar un șir de caractere simplifică tragerea variabilelor.

Apasă **Add Call**, deschide **Response & Test**, apasă **Test API Call** și vezi răspunsul în **Test Response**. `data.input.timezoneOffset` este returnat ca `4`: exact această diferență de fus orar o avea Kievul la acea dată.

## 2. Fă apelul privat

În **Advanced Settings** ale apelului, activează **Make Private**, apasă **Save**, apoi **Deploy APIs**. Acum apelul este executat într-o Firebase Cloud Function, deci proiectul are nevoie de un Firebase conectat și de un plan Firebase cu Cloud Functions.

<Aside type="caution" title="Apelurile private nu moștenesc anteturile grupului">
Dacă pui cheia pe **API Group** și nu pe apelul în sine, FlutterFlow va înceta să o trimită în momentul în care apelul devine privat: anteturile grupului nu sunt moștenite de apelurile private. Adaugă `X-Api-Key` pe apelul în sine, altfel prima rulare privată va returna `401`.
</Aside>

Încă două lucruri pe care documentația FlutterFlow le menționează direct: cheia transmisă din frontend, de exemplu prin remote config, rămâne deschisă chiar și într-un apel privat, iar forma sigură este un antet scris în apelul în sine.

## 3. Citește răspunsul

În **JSON Paths**, apasă **+ Add JSON Path** și dă fiecăruia un nume:

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

Semnul este longitudinea împărțită la 30 și rotunjită în jos, ca un index într-o listă de douăsprezece nume: de exemplu, Ascendentul `159.26` dă `5`, adică Fecioara. Este suficientă o funcție personalizată de patru rânduri sau o listă de douăsprezece rânduri și un index.

## Build-ul web nu ne poate accesa din browser

Măsurat la 2026-09-17 de pe o pagină de pe un domeniu terț: `POST /v1/chart` răspunde la preflight fără antetul `access-control-allow-origin`, iar Chrome blochează cererea. Doar `/v1/public/*` și `/v1/embed/*` răspund browserului de pe un domeniu străin.

FlutterFlow efectuează apeluri prin propriul proxy în constructor, în Run mode și Test mode, așa că un apel care funcționează acolo poate eșua după publicarea aplicației web. Două soluții, și pe prima o recomandăm:

- **Fă apelul privat**, ca mai sus. Atunci este executat într-o Cloud Function, nu în browser, și asta rezolvă imediat atât problema cheii, cât și problema CORS.
- **Pune un backend propriu în fața noastră**, dacă îl ai deja. Setările proxy în FlutterFlow, împreună cu propriul URL de proxy, sunt documentate pentru constructor și modurile Run și Test; documentația nu spune nimic despre un build web publicat, așa că nu ar trebui să te bazezi pe ele acolo.

Cheia publică `pk_` nu rezolvă asta: ea accesează doar `/v1/public/*` și `/v1/embed/*`, iar din build-urile pentru iOS și Android este respinsă complet, deoarece acestea nu trimit un web-origin.

## Erori

- **`401`** la un apel privat: cheia se află pe grup, nu pe apel.
- **`400 INVALID_FIELD` cu `timezone` în `details`**: zona este goală, este o abreviere precum `EST` sau nu este un nume de zonă.
- **`400` cu `date` sau `time` în `details`**: formatul nu este `YYYY-MM-DD` / `HH:MM:SS`.
- **`403 ENDPOINT_NOT_IN_SCOPE`**: domeniul de aplicare al cheii nu include `chart`.
- **`429 KEY_BUDGET_EXHAUSTED`**: cheia și-a epuizat bugetul; mărește-l în tabloul de bord.

<Aside type="note">
Planul gratuit FlutterFlow permite două endpoint-uri API per proiect și nu are import OpenAPI, așa că pe acesta apelul este adăugat manual, și mai rămâne un slot. API-ul nu geocodifică: coordonatele sunt preluate din câmpurile tale proprii sau dintr-un serviciu de geocodificare pentru care ai o cheie.
</Aside>
