API i endpoints
El backend exposa la majoria de dades a través d'API Platform, que genera automàticament endpoints REST/JSON a partir de les entitats marcades amb #[ApiResource]. A més, hi ha alguns controladors personalitzats per a lògica que no encaixa en el patró CRUD.
Documentació interactiva
API Platform genera una interfície Swagger/OpenAPI accessible al navegador:
https://{domini}/apiAllà es poden veure tots els endpoints, els filtres disponibles i provar les peticions en viu. És la referència sempre actualitzada. Aquesta pàgina complementa el Swagger explicant què significa cada camp de la resposta i donant-ne exemples.
Format de resposta (JSON-LD / Hydra)
Per defecte les col·leccions es retornen en format JSON-LD (capçalera Accept: application/ld+json). La resposta és un objecte amb els elements dins de member:
{
"@context": "/api/contexts/Municipality",
"@id": "/api/municipalities",
"@type": "Collection",
"totalItems": 311,
"member": [ { "...": "un element per fila" } ],
"view": {
"@id": "/api/municipalities?page=1",
"@type": "PartialCollectionView",
"first": "...", "last": "...", "next": "..."
}
}| Camp | Descripció | Exemple |
|---|---|---|
@context | Referència a la definició JSON-LD del recurs | /api/contexts/Municipality |
@id | URI de la col·lecció o de l'element | /api/municipalities/1 |
@type | Tipus del recurs | Municipality |
totalItems | Nombre total d'elements que compleixen el filtre | 311 |
member | Array amb els elements de la pàgina actual | [ {…}, {…} ] |
view | Enllaços de paginació (first, last, next, previous) | — |
Camps @id i @type
Cada objecte imbricat (p. ex. comarca, indicator) inclou també els seus @id i @type. A les taules següents s'ometen aquests dos camps tècnics per centrar-se en les dades. Si es demana amb Accept: application/json (JSON pla) s'obté un array directe, sense l'embolcall member.
Endpoints d'API Platform (entitats)
Cada entitat amb #[ApiResource] genera endpoints automàticament. Aquesta taula resumeix les operacions i la paginació.
| Recurs | Endpoint | Operacions | Paginació |
|---|---|---|---|
| Municipis | /api/municipalities | GET (col·lecció + item) | No |
| Valors de municipi | /api/municipality_values | GET (col·lecció) | Sí (311/pàgina, configurable) |
| Comarques | /api/comarcas | GET (col·lecció + item) | Per defecte (30/pàgina) |
| Valors de comarca | /api/comarca_values | GET (col·lecció) | Sí (1000/pàgina, configurable) |
| Províncies | /api/provinces/{id} | GET (només item) | — |
| Valors de província | /api/province_values | GET (col·lecció) | Sí (1000/pàgina, configurable) |
| Indicadors | /api/indicators | GET (col·lecció + item), PATCH | No |
| Fites (targets) | /api/targets | GET (col·lecció + item) | No |
| Agrupacions | /api/aggregations | GET (col·lecció + item) | No |
| Valors d'agrupació | /api/aggregation_values | GET (col·lecció) | Sí (1000/pàgina, configurable) |
| Població | /api/populations | GET (col·lecció + item) | Sí (100/pàgina, màx. 1000) |
| Pressupostos | /api/budgets | GET (col·lecció + item) | Sí (2000/pàgina) |
| Ruralitat | /api/ruralitats | GET (col·lecció + item) | Per defecte |
| Ubicació | /api/ubicacios | GET (col·lecció + item) | Per defecte |
Paginació configurable pel client
Els endpoints marcats com a configurable accepten els paràmetres page i itemsPerPage (p. ex. ?itemsPerPage=50&page=2), fins a un màxim de 10.000 elements per pàgina. Útil per evitar errors de memòria al navegador quan es baixen moltes dades des del Swagger. El límit per defecte és prou alt perquè les consultes filtrades habituals retornin tots els resultats en una sola pàgina.
Serialització per grups
Els camps que apareixen a cada resposta es controlen amb grups de serialització (#[Groups(...)]) a les entitats. Per això, p. ex., /api/targets inclou els seus indicadors imbricats, però /api/comarca_values només mostra un subconjunt dels camps de l'indicador.
Municipis — /api/municipalities
| Camp | Descripció | Exemple |
|---|---|---|
id | Clau primària interna | 1 |
municipality_name | Nom del municipi | Polinyà |
municipality_code | Codi INE de 5 dígits | 08167 |
municipality_code_6 | Codi INE de 6 dígits (amb dígit de control) | 081672 |
comarca.comarca_name | Nom de la comarca | Vallès Occidental |
comarca.comarca_code | Codi de la comarca | 40 |
population | Última població disponible (dada de resum) | 8581 |
population_year | Any de la dada de població | 2026 |
aggregations[].name | Nom de cada agrupació a què pertany | No rural |
aggregations[].slug | Identificador curt de l'agrupació | no-rural |
aggregations[].group | Família de l'agrupació (ruralitat, ubicacio, regional-flag, territorial-region) | ruralitat |
Classificacions territorials via aggregations
Tota la classificació territorial d'un municipi (ruralitat, ubicació, industrial, AMB, RMB, regió territorial) s'obté a través de aggregations, filtrant per group o slug. Els camps antics ubicacio, ruralitat, industrial, in_amb, in_rmb i territorial_region ja no s'exposen a l'API (són obsolets).
Exemple de resposta (un element de member):
{
"id": 1,
"municipality_name": "Polinyà",
"municipality_code": "08167",
"municipality_code_6": "081672",
"comarca": { "comarca_name": "Vallès Occidental", "comarca_code": "40" },
"population": 8581,
"population_year": 2026,
"aggregations": [
{ "id": 4, "name": "No rural", "slug": "no-rural", "group": "ruralitat" },
{ "id": 7, "name": "Interior", "slug": "interior", "group": "ubicacio" }
]
}Valors de municipi — /api/municipality_values
Valor d'un indicador per a un municipi i un any concrets. És l'endpoint amb més volum de dades; s'usa gairebé sempre amb filtres.
| Camp | Descripció | Exemple |
|---|---|---|
municipality.id | Clau primària del municipi | 220 |
municipality.municipality_name | Nom del municipi | Abrera |
municipality.municipality_code | Codi INE de 5 dígits | 08001 |
municipality.municipality_code_6 | Codi INE de 6 dígits | 080018 |
indicator.id | Clau primària de l'indicador | 42 |
indicator.indicator_id | Codi de l'indicador ({ods}.{fita}.{indicador}) | 1.4.2 |
indicator.name | Nom de l'indicador | Proporció de persones amb discapacitat que reben una pensió |
value | Valor principal (numerador). Vegeu la nota sobre value i value2 | 19 |
value2 | Valor secundari (denominador), si l'indicador n'usa | 1327 |
subindicator | Índex de subindicador, si l'indicador en té | null |
year | Any de la dada | 2023 |
Què signifiquen value i value2
Molts indicadors es calculen com una ràtio: value és el numerador i value2 el denominador (p. ex. persones amb pensió / total de persones amb discapacitat). Guardar-los per separat permet reagregar correctament a nivell de comarca, província o agrupació. Els indicadors simples només tenen value. Vegeu Model de dades per al detall de cada camp.
Els camps value2 i subindicator només apareixen a la resposta quan tenen valor; si són nuls, s'ometen.
Exemple de resposta:
{
"municipality": {
"id": 220,
"municipality_name": "Abrera",
"municipality_code": "08001",
"municipality_code_6": "080018"
},
"indicator": { "id": 42, "indicator_id": "1.4.2", "name": "Proporció de persones amb discapacitat que reben una pensió" },
"value": 19,
"value2": 1327,
"year": 2023
}Comarques — /api/comarcas
| Camp | Descripció | Exemple |
|---|---|---|
id | Clau primària | 1 |
comarca_name | Nom de la comarca | Vallès Occidental |
comarca_code | Codi de la comarca | 40 |
Exemple de resposta:
{
"id": 1,
"comarca_name": "Vallès Occidental",
"comarca_code": "40"
}Municipis i valors d'una comarca
La col·lecció de comarques ja no incrusta les llistes de municipis ni de valors. Els valors d'una comarca es consulten amb /api/comarca_values?comarca.comarca_code={codi}. Per als municipis d'una comarca, cada element de /api/municipalities porta el seu comarca.comarca_code imbricat, de manera que es poden agrupar pel costat del client.
Valors de comarca — /api/comarca_values
Valor agregat d'un indicador a nivell de comarca. Sovint porta dos valors: value (numerador) i value2 (denominador), per poder recalcular ràtios.
| Camp | Descripció | Exemple |
|---|---|---|
comarca.comarca_name | Nom de la comarca | Baix Llobregat |
comarca.comarca_code | Codi de la comarca | 11 |
indicator.indicator_id | Codi de l'indicador | 1.4.2 |
indicator.name | Nom de l'indicador | Proporció de persones amb discapacitat que reben una pensió |
value | Valor principal (o numerador) | 2145 |
value2 | Valor secundari (denominador), si aplica | 74013 |
subindicator | Índex de subindicador, si l'indicador en té | null |
year | Any de la dada | 2023 |
Exemple de resposta:
{
"comarca": { "comarca_name": "Baix Llobregat", "comarca_code": "11" },
"indicator": { "indicator_id": "1.4.2", "name": "Proporció de persones amb discapacitat que reben una pensió" },
"value": 2145,
"value2": 74013,
"year": 2023
}Valors de província — /api/province_values
Idèntic a comarca_values però agregat a nivell de província.
| Camp | Descripció | Exemple |
|---|---|---|
province.province_code | Codi de la província | 8 |
province.province_name | Nom de la província | Barcelona |
indicator.indicator_id | Codi de l'indicador | 1.4.2 |
indicator.name | Nom de l'indicador | Proporció de persones amb discapacitat que reben una pensió |
value | Valor principal (o numerador) | 17655 |
value2 | Valor secundari (denominador), si aplica | 501657 |
subindicator | Índex de subindicador, si l'indicador en té | null |
year | Any de la dada | 2023 |
Exemple de resposta:
{
"province": { "province_code": "8", "province_name": "Barcelona" },
"indicator": { "indicator_id": "1.4.2", "name": "Proporció de persones amb discapacitat que reben una pensió" },
"value": 17655,
"value2": 501657,
"year": 2023
}Valors d'agrupació — /api/aggregation_values
Valor precalculat d'un indicador per a una agrupació territorial (rural, litoral, AMB, etc.).
| Camp | Descripció | Exemple |
|---|---|---|
aggregation.name | Nom de l'agrupació | Rural |
aggregation.slug | Identificador curt de l'agrupació | rural |
aggregation.group | Família de l'agrupació | ruralitat |
indicator.indicator_id | Codi de l'indicador | 1.2.3 |
indicator.name | Nom de l'indicador | Nombre de socis de cooperatives per 1.000 habitants |
value | Valor principal (o numerador) | 712 |
value2 | Valor secundari (denominador), si aplica | 69622 |
subindicator | Índex de subindicador, si l'indicador en té | null |
year | Any de la dada | 2025 |
Exemple de resposta:
{
"aggregation": { "name": "Rural", "slug": "rural", "group": "ruralitat" },
"indicator": { "indicator_id": "1.2.3", "name": "Nombre de socis de cooperatives per 1.000 habitants" },
"value": 712,
"value2": 69622,
"year": 2025
}Indicadors — /api/indicators
Catàleg d'indicadors. Cada indicador porta la seva fita (target) imbricada i uns comptadors de cobertura calculats.
| Camp | Descripció | Exemple |
|---|---|---|
id | Clau primària | 1 |
target.sdg | Número de l'ODS de la fita (1–17) | 1 |
target.target_id | Codi de la fita | 1.2 |
indicator_id | Codi de l'indicador | 1.2.1 |
name | Nom de l'indicador | % Població amb ingressos < 60% |
sign | true = més alt és millor; false = més baix és millor | false |
unit | Unitat de mesura interna | percent |
scale | Factor d'escala heretat (no s'usa al backend) | 1 |
weight | Pes de l'indicador per al càlcul de l'ODS sintètic (0–100) | 45 |
calculation | Estratègia de càlcul | simple |
dimension_weight | Pes de la dimensió per al càlcul sintètic (0–100) | 0 |
municipalityCount | Nombre de municipis amb dades per a l'indicador | 246 |
yearCount | Nombre d'anys amb dades disponibles | 9 |
lastYearAvailable | Últim any amb dades | 2023 |
mostRecentDate | Data de la darrera actualització de dades | 2026-06-02T13:04:32+00:00 |
Exemple de resposta:
{
"id": 1,
"target": { "id": 1, "sdg": 1, "target_id": "1.2" },
"indicator_id": "1.2.1",
"name": "% Població amb ingressos < 60%",
"sign": false,
"unit": "percent",
"scale": "1",
"weight": 45,
"calculation": "simple",
"dimension_weight": 0,
"municipalityCount": 246,
"yearCount": 9,
"lastYearAvailable": 2023,
"mostRecentDate": "2026-06-02T13:04:32+00:00"
}El camp sign (sentit de l'indicador)
sign indica en quin sentit s'ha d'interpretar el valor de l'indicador:
sign: true→ com més alt, millor (p. ex. Renda mediana: un valor més gran és una situació més bona).sign: false→ com més baix, millor (p. ex. % Població amb ingressos < 60%: un valor més gran és una situació més dolenta).
S'usa per orientar correctament els colors, els rànquings i el càlcul de la puntuació sintètica: sense sign, no es podria saber si pujar de valor és positiu o negatiu.
Els textos visibles no surten d'aquí
Els camps name, unit i description de l'indicador tenen un valor intern de referència, però el text que es mostra a la interfície prové de les etiquetes de llengua del frontend (vegeu Textos i etiquetes), no d'aquest endpoint.
Fites — /api/targets
Fita ODS amb la col·lecció d'indicadors que la componen imbricada.
| Camp | Descripció | Exemple |
|---|---|---|
id | Clau primària | 20 |
sdg | Número de l'ODS (1–17) | 1 |
target_id | Codi de la fita | 1.1 |
target_name | Nom descriptiu de la fita | Reduir la pobresa extrema |
indicators[].indicator_id | Codi de cada indicador de la fita | 1.1.1 |
indicators[].name | Nom de l'indicador | % Població amb ingressos < 40% |
indicators[].sign | Sentit de l'indicador: true = més alt és millor; false = més baix és millor | true |
indicators[].unit | Unitat interna | percent |
indicators[].description | Descripció de l'indicador | Percentatge de població… |
indicators[].weight | Pes per al càlcul sintètic | 0 |
indicators[].calculation | Estratègia de càlcul | simple |
indicators[].dimension_weight | Pes de dimensió | 20 |
Exemple de resposta:
{
"id": 20,
"sdg": 1,
"target_id": "1.1",
"target_name": "Reduir la pobresa extrema",
"indicators": [
{
"id": 27,
"indicator_id": "1.1.1",
"name": "% Població amb ingressos < 40%",
"sign": true,
"unit": "percent",
"description": "Percentatge de població que viu en unitats de consum amb una renda disponible inferior al 40% de la mitjana",
"weight": 0,
"calculation": "simple",
"dimension_weight": 20
}
]
}Agrupacions — /api/aggregations
Catàleg d'agrupacions territorials.
| Camp | Descripció | Exemple |
|---|---|---|
id | Clau primària | 1 |
name | Nom de l'agrupació | Rural |
slug | Identificador curt | rural |
group | Família de l'agrupació (ruralitat, ubicacio, regional-flag, territorial-region) | ruralitat |
Exemple de resposta:
{ "id": 1, "name": "Rural", "slug": "rural", "group": "ruralitat" }Població — /api/populations
Sèrie històrica de població per municipi i any.
| Camp | Descripció | Exemple |
|---|---|---|
municipality.municipality_name | Nom del municipi | Polinyà |
municipality.municipality_code | Codi INE de 5 dígits | 08167 |
population_count | Habitants aquell any | 8555 |
year | Any de la dada | 2024 |
Exemple de resposta:
{
"municipality": { "municipality_name": "Polinyà", "municipality_code": "08167" },
"population_count": 8555,
"year": 2024
}Pressupostos — /api/budgets
Despesa pressupostària per municipi, programa i any.
| Camp | Descripció | Exemple |
|---|---|---|
year | Any del pressupost | 2010 |
value | Import (€) | 759806 |
program | Codi de programa pressupostari | 1 |
municipality | URI del municipi | /api/municipalities/283 |
Exemple de resposta:
{ "year": 2010, "value": 759806, "program": "1", "municipality": "/api/municipalities/283" }Filtres habituals
Els filtres es declaren amb #[ApiFilter(...)] a l'entitat i es tradueixen automàticament en paràmetres de consulta.
# Valors d'un indicador per a un any
GET /api/municipality_values?indicator.indicator_id=1.2.1&year=2023
# Valors d'un municipi concret (codi INE)
GET /api/municipality_values?municipality.municipality_code=08019
# Municipis d'una agrupació
GET /api/municipalities?aggregations.slug=rural
# Fites d'un ODS concret
GET /api/targets?sdg=3
# Valors d'agrupació per slug i indicador
GET /api/aggregation_values?aggregation.slug=rural&indicator.indicator_id=1.2.1
# Ordenació
GET /api/municipalities?order[municipality_name]=ascFiltres disponibles per recurs (els més usats):
| Recurs | Filtres SearchFilter | Filtres OrderFilter |
|---|---|---|
municipality_values | municipality.id, municipality.municipality_code, municipality.municipality_code_6, municipality.comarca.comarca_code, municipality.aggregations.slug, indicator.indicator_id, indicator.target.sdg, year | year, value |
municipalities | aggregations.slug | municipality_name, municipality_code_6 |
comarca_values | comarca.id, comarca.comarca_code, indicator.indicator_id, indicator.target.target_id, indicator.id, year | — |
province_values | indicator.indicator_id, indicator.target.target_id, indicator.id, year | — |
aggregation_values | aggregation, aggregation.slug, indicator, indicator.indicator_id, year | — |
aggregations | group, slug | — |
targets | sdg | — |
budgets | municipality.*, program, year | program |
populations | year, municipality.municipality_code | — |
Controladors personalitzats
Per a lògica que no és CRUD pur, hi ha controladors a src/Controller/. A diferència dels endpoints d'API Platform, retornen JSON pla (un array o objecte directe, sense l'embolcall member).
| Endpoint | Mètode | Descripció |
|---|---|---|
/api/synthetic-sdg | GET | Puntuació sintètica per ODS (vegeu ODS sintètics) |
/api/sdg-indicators | GET | Valors en brut dels indicadors d'un ODS |
/api/municipalities-under-weight | GET | Entitats amb cobertura d'indicadors insuficient |
/api/labels-hierarchy | GET | Etiquetes/textos de la UI (jerarquia) |
/api/labels-import | POST | Desa etiquetes editades (requereix JWT) |
/api/etl/{indicator_id} | POST | Dispara la importació ETL d'un indicador via HTTP |
/export/csv | GET | Exporta valors a CSV |
/export/indicators | GET | Exporta el catàleg d'indicadors a CSV |
/api/login | POST | Autenticació JWT (retorna token) |
/api/synthetic-sdg — Puntuació sintètica per ODS
Retorna la puntuació sintètica (0–100) de cada ODS per a una entitat.
Paràmetres de consulta:
| Paràmetre | Descripció | Exemple |
|---|---|---|
type | Tipus d'entitat: municipality (per defecte), comarca, aggregation | comarca |
municipality_code | Codi INE de 5 dígits (per a type=municipality) | 08019 |
comarca_code | Codi de comarca (per a type=comarca) | 11 |
aggregation_slug | Slug de l'agrupació (per a type=aggregation) | rural |
sdg | Filtra a un ODS concret (opcional) | 3 |
global | Si és true, retorna també les puntuacions per dimensió | 1 |
Camps de resposta:
| Camp | Descripció | Exemple |
|---|---|---|
sdg | Número de l'ODS | 1 |
code | Codi de l'entitat | 080193 |
name | Nom de l'entitat | Barcelona |
population | Població (només per a municipis; null per a comarca/agrupació) | 1731649 |
value | Puntuació sintètica de l'ODS (0–100) | 49.74 |
municipality_code_6 | Codi de 6 dígits (només per a municipis) | 080193 |
municipality_name | Nom del municipi (només per a municipis) | Barcelona |
Exemple de resposta (type=municipality):
[
{ "sdg": 1, "code": "080193", "name": "Barcelona", "population": 1731649, "value": 49.74, "municipality_code_6": "080193", "municipality_name": "Barcelona" },
{ "sdg": 2, "code": "080193", "name": "Barcelona", "population": 1731649, "value": 29.83, "municipality_code_6": "080193", "municipality_name": "Barcelona" }
]/api/sdg-indicators — Valors en brut d'un ODS
Retorna els valors de tots els indicadors d'un ODS per a tots els municipis (o filtrats).
Paràmetres de consulta:
| Paràmetre | Descripció | Exemple |
|---|---|---|
sdg | Obligatori. Número de l'ODS | 1 |
municipality.municipality_code | Filtra per municipi (opcional) | 08019 |
Camps de resposta:
| Camp | Descripció | Exemple |
|---|---|---|
value | Valor de l'indicador | 10.5 |
value2 | Valor secundari (denominador), si aplica | null |
year | Any de la dada | 2023 |
municipality_code | Codi INE de 5 dígits | 08001 |
municipality_name | Nom del municipi | Abrera |
municipality_code_6 | Codi INE de 6 dígits | 080018 |
population | Població del municipi | 13227 |
indicator_id | Codi de l'indicador | 1.2.1 |
sdg | Número de l'ODS | 1 |
Exemple de resposta:
[
{
"value": 10.5, "value2": null, "year": 2023,
"municipality_code": "08001", "municipality_name": "Abrera", "municipality_code_6": "080018",
"population": 13227, "indicator_id": "1.2.1", "sdg": 1
}
]/api/labels-hierarchy — Textos de la interfície
Retorna l'arbre d'etiquetes de la UI en l'idioma demanat. La resposta és un objecte JSON niat (no una llista); les claus són identificadors de text i els valors, cadenes o subobjectes.
Paràmetres de consulta: language (p. ex. ca, es, en).
Exemple de resposta:
{
"TITLE": "Visor 2030",
"HOMEPAGE": {
"TITLE": "Indicadors locals ODS de la província de Barcelona",
"DESCRIPTION": "Des de la Diputació de Barcelona posem al vostre abast…"
}
}Exportacions CSV — /export/csv i /export/indicators
Retornen un fitxer CSV (Content-Disposition: attachment), no JSON.
/export/csv— exporta els valors d'un ODS o indicador. Paràmetres:id(obligatori, un ODS1–17o un codi d'indicadorX.X.X),municipalityiyear(opcionals)./export/indicators— exporta el catàleg complet d'indicadors.
/api/etl/{indicator_id} — Disparar importació ETL
Executa la importació ETL d'un indicador. Accepta opcionalment un fitxer CSV al cos de la petició (multipart/form-data). Requereix JWT.
Resposta d'èxit:
{ "status": "Indicator 1.2.1 imported successfully" }Resposta d'error (p. ex. indicador no trobat):
{ "error": "Indicator 1.2.1 not found" }Autenticació
Els endpoints de lectura són públics. Els d'escriptura (p. ex. POST /api/labels-import, POST /api/etl/{indicator_id}) requereixen un token JWT.
Obtenir un token
POST /api/login
Content-Type: application/json
{ "username": "usuari", "password": "contrasenya" }La resposta conté el token:
{ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..." }S'envia a les peticions protegides amb la capçalera:
Authorization: Bearer {token}La configuració JWT es troba a config/packages/lexik_jwt_authentication.yaml i les regles d'accés a config/packages/security.yaml. Vegeu Instal·lació per a la generació de claus.