# Inicio rápido
URL: https://docs.fluenta.io/docs/quickstart

De cero a tu primera respuesta en cinco pasos, con curl, JavaScript y Python.



Al terminar esta página habrás creado un token de API, sabrás a qué
organizaciones llega y habrás leído los módulos y una cifra de eficiencia de
una de ellas.

La URL base es `https://api.fluenta.io/v1/external`. Cada solicitud lleva el
token en el encabezado `Authorization`.

## 1. Crea un token [#1-crea-un-token]

1. Entra a `app.fluenta.io` y abre «Configuración» → «Tokens de API».
2. Pulsa «Crear token». Escribe un «Nombre», deja el permiso «Leer» y elige un
   «Vencimiento».
3. En la ventana «Token creado», pulsa «Copiar token». El token se muestra una
   sola vez.

Guárdalo en una variable de entorno:

```bash
export FLUENTA_TOKEN='fluenta_live_xxxxxxxxxxxxxxxx'
```

## 2. Comprueba el token [#2-comprueba-el-token]

```bash
curl https://api.fluenta.io/v1/external/me \
  -H "Authorization: Bearer $FLUENTA_TOKEN"
```

```json
{
  "user": { "name": "Ana Pérez", "roles": ["ADMIN"] },
  "connection": {
    "app": "Reporte semanal",
    "scopes": ["read"],
    "expiresAt": "2027-02-09T15:04:05.000Z"
  },
  "credential": {
    "kind": "personal",
    "name": "Reporte semanal",
    "prefix": "fluenta_live_xxx",
    "expiresAt": "2027-02-09T15:04:05.000Z"
  },
  "rateLimit": { "limit": 60, "remaining": 59, "reset": 1794355260 },
  "organizations": [
    { "id": 42, "name": "Confecciones Ejemplo", "connectorEnabled": true }
  ],
  "organizationsTotal": 1,
  "reachesAllOrganizations": false
}
```

`user` es la persona como la que actúa el token: tú. `credential.kind` es
`personal` para un token de API.

## 3. Lista tus organizaciones [#3-lista-tus-organizaciones]

`/me` trae las primeras 50. Esta ruta las pagina y las busca por nombre:

```bash
curl https://api.fluenta.io/v1/external/organizations \
  -H "Authorization: Bearer $FLUENTA_TOKEN"
```

```json
{
  "items": [
    { "id": 42, "name": "Confecciones Ejemplo", "connectorEnabled": true }
  ],
  "page": 1,
  "total": 1
}
```

El `id` es el `organizationId` de todas las demás rutas.

## 4. Lee los módulos de una organización [#4-lee-los-módulos-de-una-organización]

```bash
curl https://api.fluenta.io/v1/external/organizations/42/modules \
  -H "Authorization: Bearer $FLUENTA_TOKEN"
```

```json
[
  { "id": 7, "name": "Módulo 1", "position": 0, "stationCount": 12, "colorHue": null }
]
```

`GET /organizations/42/floor` responde los módulos con sus puestos en una sola
respuesta. Cuenta contra un límite de uso más bajo: mira
[Límites de uso](/docs/rate-limits).

## 5. Lee una cifra [#5-lee-una-cifra]

La eficiencia de la planta hoy, desde el tablero en vivo. Esta ruta está en
todos los planes:

```bash
curl https://api.fluenta.io/v1/external/organizations/42/board \
  -H "Authorization: Bearer $FLUENTA_TOKEN"
```

La respuesta, aquí sin su lista `modules` (una fila por módulo):

```json
{
  "day": "2026-11-10",
  "plant": {
    "produced": 1840,
    "goal": 2000,
    "efficiency": 92,
    "modules": 1,
    "producing": 1,
    "lastClosed": { "day": "2026-11-09", "efficiency": 88.5 },
    "closed": { "average": 91.3, "modules": 1 }
  }
}
```

`plant.efficiency` es un porcentaje: 92 quiere decir 92% de la meta.

### Opcional: un rango de días [#opcional-un-rango-de-días]

La eficiencia día por día sale de una ruta de reportes. Los días van como
`YYYY-MM-DD`, en el reloj de la planta:

```bash
curl "https://api.fluenta.io/v1/external/organizations/42/analytics/efficiency?from=2026-11-10&to=2026-11-10" \
  -H "Authorization: Bearer $FLUENTA_TOKEN"
```

```json
{
  "from": "2026-11-10",
  "to": "2026-11-10",
  "groupBy": "day",
  "page": 1,
  "pageSize": 100,
  "total": 1,
  "items": [
    { "day": "2026-11-10", "units": 1840, "goal": 2000, "efficiency": 92 }
  ]
}
```

Esta ruta sigue el plan. Una organización cuyo plan no incluye reportes
responde 403 con `"code": "PLAN_LIMIT"`: el token está bien, y `/board` sigue
respondiendo. Los dos programas de abajo leen `/board` primero, luego intentan
el rango y avisan cuando el plan no lo incluye. El detalle está en
[Planes](/docs/plans).

## Lo mismo en JavaScript [#lo-mismo-en-javascript]

Guárdalo como `inicio.mjs` y ejecútalo con Node.js:

```js
const BASE = 'https://api.fluenta.io/v1/external';
const headers = { Authorization: `Bearer ${process.env.FLUENTA_TOKEN}` };

async function get(path) {
  const response = await fetch(`${BASE}${path}`, { headers });
  const body = await response.json();
  if (!response.ok) {
    const error = new Error(`${body.code}: ${body.message}`);
    error.code = body.code;
    throw error;
  }
  return body;
}

const me = await get('/me');
const { items } = await get('/organizations');
const organizationId = items[0].id;
const modules = await get(`/organizations/${organizationId}/modules`);
const board = await get(`/organizations/${organizationId}/board`);

console.log(me.user.name, modules.length, board.plant.efficiency);

// Opcional: un rango de días. Esta ruta sigue el plan.
try {
  const range = await get(
    `/organizations/${organizationId}/analytics/efficiency?from=2026-11-10&to=2026-11-10`
  );
  console.log(range.items);
} catch (error) {
  if (error.code !== 'PLAN_LIMIT') throw error;
  console.log('Este plan no incluye reportes.');
}
```

## Lo mismo en Python [#lo-mismo-en-python]

```python
import os

import requests

BASE = "https://api.fluenta.io/v1/external"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['FLUENTA_TOKEN']}"


class ApiError(RuntimeError):
    def __init__(self, body):
        super().__init__(f"{body['code']}: {body['message']}")
        self.code = body["code"]


def get(path, params=None):
    response = session.get(f"{BASE}{path}", params=params, timeout=30)
    body = response.json()
    if not response.ok:
        raise ApiError(body)
    return body


me = get("/me")
organization_id = get("/organizations")["items"][0]["id"]
modules = get(f"/organizations/{organization_id}/modules")
board = get(f"/organizations/{organization_id}/board")

print(me["user"]["name"], len(modules), board["plant"]["efficiency"])

# Opcional: un rango de días. Esta ruta sigue el plan.
try:
    efficiency = get(
        f"/organizations/{organization_id}/analytics/efficiency",
        {"from": "2026-11-10", "to": "2026-11-10"},
    )
    print(efficiency["items"])
except ApiError as error:
    if error.code != "PLAN_LIMIT":
        raise
    print("Este plan no incluye reportes.")
```

## Qué leer después [#qué-leer-después]

* [Autenticación](/docs/authentication): guardar, rotar y revocar el token.
* [Permisos](/docs/permissions): qué hace falta para escribir en el Programa.
* [Organizaciones y recursos](/docs/organizations): cómo pasan los ids de una
  llamada a la siguiente.
* [Planes](/docs/plans): qué rutas responde cada plan.
* [Errores](/docs/errors) y [Convenciones](/docs/conventions).
* La [referencia](/docs/reference) tiene una página por operación.
