# Quickstart
URL: https://docs.fluenta.io/en/docs/quickstart

From zero to your first answer in five steps, with curl, JavaScript and Python.



By the end of this page you will have created an API token, know which
organizations it reaches, and have read the modules and one efficiency figure
of one of them.

The base URL is `https://api.fluenta.io/v1/external`. Every request carries
the token in the `Authorization` header.

## 1. Create a token [#1-create-a-token]

The dashboard is in Spanish; its labels are quoted here as it prints them.

1. Sign in at `app.fluenta.io` and open «Configuración» (Settings) → «Tokens
   de API» (API tokens).
2. Press «Crear token» (Create token). Type a «Nombre» (name), keep the «Leer»
   (Read) permission and pick a «Vencimiento» (expiry).
3. In the «Token creado» (Token created) window, press «Copiar token» (Copy
   token). The token is shown once.

Keep it in an environment variable:

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

## 2. Check the token [#2-check-the-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` is the person the token acts as: you. `credential.kind` is `personal`
for an API token.

## 3. List your organizations [#3-list-your-organizations]

`/me` carries the first 50. This route pages them and searches them by name:

```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
}
```

The `id` is the `organizationId` of every other route.

## 4. Read the modules of one organization [#4-read-the-modules-of-one-organization]

```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` answers the modules with their stations in one
response. It counts against a lower rate limit: see
[Rate limits](/en/docs/rate-limits).

## 5. Read one figure [#5-read-one-figure]

The plant's efficiency for today, from the live board. This route is on every
plan:

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

The response, shown here without its `modules` list (one row per module):

```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` is a percentage: 92 means 92% of the goal.

### Optional: a range of days [#optional-a-range-of-days]

Efficiency day by day comes from a report route. Days are `YYYY-MM-DD`, on the
plant's clock:

```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 }
  ]
}
```

This route follows the plan. An organization whose plan does not include
reports answers 403 with `"code": "PLAN_LIMIT"`: nothing is wrong with the
token, and `/board` above keeps answering. The two programs below read `/board`
first, then try the range and say so when the plan does not include it.
[Plans](/en/docs/plans) has the detail.

## The same in JavaScript [#the-same-in-javascript]

Save it as `quickstart.mjs` and run it with 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);

// Optional: a range of days. This route follows the 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('This plan does not include reports.');
}
```

## The same in Python [#the-same-in-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"])

# Optional: a range of days. This route follows the 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("This plan does not include reports.")
```

## What to read next [#what-to-read-next]

* [Authentication](/en/docs/authentication): storing, rotating and revoking
  the token.
* [Permissions](/en/docs/permissions): what writing to the «Programa» (each
  module's production queue) takes.
* [Organizations and resources](/en/docs/organizations): how ids flow from one
  call to the next.
* [Plans](/en/docs/plans): which routes each plan answers.
* [Errors](/en/docs/errors) and [Conventions](/en/docs/conventions).
* The [reference](/en/docs/reference) has one page per operation.
