# FlutterFlow

FlutterFlow se compila en una aplicación que tiene en sus manos tu usuario, así que la cuestión no es qué campos rellenar, sino dónde termina la clave. La solicitud a continuación se envía a producción exactamente en la forma en que la construye la llamada; los pasos en FlutterFlow están escritos según la documentación de FlutterFlow al 2026-09-17.

Primero crea una clave, como se describe en la sección [Clave para automatización](/integrations/#ключ-для-автоматизації), con el ámbito `chart`.

<Aside type="caution" title="Ключ у звичайному виклику їде разом із застосунком">
Una llamada que no está marcada como privada se ejecuta desde el dispositivo, y su encabezado queda dentro del paquete compilado para iOS, Android y web, donde cualquiera puede leerlo. Haz la llamada **privada**: entonces FlutterFlow la ejecuta a través de Firebase Cloud Function, y la clave permanece en el servidor. La verificación propia de FlutterFlow consiste en descargar el código del proyecto y buscar la clave en los archivos del frontend, y solo está disponible en el plan de pago.
</Aside>

## 1. Crea la llamada

Abre **API Calls**, haz clic en **+ Add**, selecciona **Create API Call** y completa:

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

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

- Pestaña **Headers**, **+ Add Header**: una línea `X-Api-Key: ` seguida de tu clave. Otra línea `Content-Type: application/json`.
- Pestaña **Variables**: cinco variables de tipo String, `date`, `time`, `timezone`, `latitude`, `longitude`, cada una con un valor por defecto del JSON a continuación.
- Pestaña **Body**, en la lista desplegable **JSON**: inserta el JSON y arrastra en él las variables.

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

La latitud y longitud se dejan como cadenas a propósito: la API acepta `"50.45"` como número, y la cadena simplifica arrastrar las variables.

Haz clic en **Add Call**, abre **Response & Test**, pulsa **Test API Call** y mira la respuesta en **Test Response**. `data.input.timezoneOffset` se devuelve como `4`: ese es el desplazamiento de Kyiv en esa fecha.

## 2. Haz la llamada privada

En **Advanced Settings** de la llamada activa **Make Private**, haz clic en **Save**, luego en **Deploy APIs**. Ahora la llamada se ejecuta en Firebase Cloud Function, por lo que el proyecto necesita Firebase conectado y un plan de Firebase con Cloud Functions.

<Aside type="caution" title="Приватні виклики не успадковують заголовки групи">
Si colocas la clave en el **API Group**, y no en la propia llamada, FlutterFlow dejará de enviarla en el mismo momento en que la llamada se vuelva privada: los encabezados del grupo no se heredan en llamadas privadas. Añade `X-Api-Key` a la propia llamada, de lo contrario el primer lanzamiento privado devolverá `401`.
</Aside>

Dos cosas más que la documentación de FlutterFlow dice claramente: la clave enviada desde el frontend, por ejemplo a través de remote config, sigue estando expuesta incluso en una llamada privada, y la forma segura es el encabezado incluido en la propia llamada.

## 3. Lee la respuesta

En **JSON Paths** haz clic en **+ Add JSON Path** y asigna un nombre a cada uno:

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

El signo es la longitud dividida por 30 y redondeada hacia abajo, como índice en una lista de doce nombres: por ejemplo, Ascendente `159.26` da `5`, es decir, Virgo. Basta con una función personalizada de cuatro líneas o una lista de doce elementos y el índice.

## La compilación web no puede llamarnos desde el navegador

Medido el 2026-09-17 desde una página en dominio externo: `POST /v1/chart` responde al preflight sin el encabezado `access-control-allow-origin`, y Chrome bloquea la solicitud. Al navegador en dominio externo solo responden `/v1/public/*` y `/v1/embed/*`.

FlutterFlow realiza las llamadas a través de su propio proxy en el constructor, en Run mode y Test mode, por lo que una llamada que funciona allí puede fallar después de publicar la aplicación web. Hay dos soluciones, y recomendamos la primera:

- **Haz la llamada privada**, como arriba. Entonces se ejecuta en Cloud Function, no en el navegador, y eso elimina tanto el problema de la clave como el de CORS.
- **Coloca tu propio backend delante de nosotros**, si ya lo tienes. La configuración del proxy en FlutterFlow, junto con tu propio proxy URL, está documentada para el constructor y los modos Run y Test; la documentación no menciona la compilación web publicada, así que no deberías contar con ello.

Una clave pública `pk_` no soluciona esto: solo accede a `/v1/public/*` y `/v1/embed/*`, y desde compilaciones para iOS y Android se rechaza por completo, ya que no envían web-origin.

## Errores

- **`401`** en una llamada privada: la clave está en el grupo, no en la llamada.
- **`400 INVALID_FIELD` con `timezone` en `details`**: zona vacía, es una abreviatura como `EST` o no es un nombre de zona.
- **`400` con `date` o `time` en `details`**: el formato no es `YYYY-MM-DD` / `HH:MM:SS`.
- **`403 ENDPOINT_NOT_IN_SCOPE`**: el ámbito de la clave no incluye `chart`.
- **`429 KEY_BUDGET_EXHAUSTED`**: la clave agotó su presupuesto; aumentalo en el dashboard.

<Aside type="note">
El plan gratuito de FlutterFlow permite dos API-endpoints por proyecto y no tiene importación OpenAPI, por lo que la llamada se agrega manualmente, quedando un slot disponible. La API no geocodifica: las coordenadas se toman de tus propios campos o de un servicio de geocodificación del que dispones una clave.
</Aside>
