Vés al contingut

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}/api

Allà 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:

json
{
  "@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": "..."
  }
}
CampDescripcióExemple
@contextReferència a la definició JSON-LD del recurs/api/contexts/Municipality
@idURI de la col·lecció o de l'element/api/municipalities/1
@typeTipus del recursMunicipality
totalItemsNombre total d'elements que compleixen el filtre311
memberArray amb els elements de la pàgina actual[ {…}, {…} ]
viewEnllaç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ó.

RecursEndpointOperacionsPaginació
Municipis/api/municipalitiesGET (col·lecció + item)No
Valors de municipi/api/municipality_valuesGET (col·lecció)Sí (311/pàgina, configurable)
Comarques/api/comarcasGET (col·lecció + item)Per defecte (30/pàgina)
Valors de comarca/api/comarca_valuesGET (col·lecció)Sí (1000/pàgina, configurable)
Províncies/api/provinces/{id}GET (només item)
Valors de província/api/province_valuesGET (col·lecció)Sí (1000/pàgina, configurable)
Indicadors/api/indicatorsGET (col·lecció + item), PATCHNo
Fites (targets)/api/targetsGET (col·lecció + item)No
Agrupacions/api/aggregationsGET (col·lecció + item)No
Valors d'agrupació/api/aggregation_valuesGET (col·lecció)Sí (1000/pàgina, configurable)
Població/api/populationsGET (col·lecció + item)Sí (100/pàgina, màx. 1000)
Pressupostos/api/budgetsGET (col·lecció + item)Sí (2000/pàgina)
Ruralitat/api/ruralitatsGET (col·lecció + item)Per defecte
Ubicació/api/ubicaciosGET (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

CampDescripcióExemple
idClau primària interna1
municipality_nameNom del municipiPolinyà
municipality_codeCodi INE de 5 dígits08167
municipality_code_6Codi INE de 6 dígits (amb dígit de control)081672
comarca.comarca_nameNom de la comarcaVallès Occidental
comarca.comarca_codeCodi de la comarca40
populationÚltima població disponible (dada de resum)8581
population_yearAny de la dada de població2026
aggregations[].nameNom de cada agrupació a què pertanyNo rural
aggregations[].slugIdentificador curt de l'agrupacióno-rural
aggregations[].groupFamí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):

json
{
  "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.

CampDescripcióExemple
municipality.idClau primària del municipi220
municipality.municipality_nameNom del municipiAbrera
municipality.municipality_codeCodi INE de 5 dígits08001
municipality.municipality_code_6Codi INE de 6 dígits080018
indicator.idClau primària de l'indicador42
indicator.indicator_idCodi de l'indicador ({ods}.{fita}.{indicador})1.4.2
indicator.nameNom de l'indicadorProporció de persones amb discapacitat que reben una pensió
valueValor principal (numerador). Vegeu la nota sobre value i value219
value2Valor secundari (denominador), si l'indicador n'usa1327
subindicatorÍndex de subindicador, si l'indicador en ténull
yearAny de la dada2023

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:

json
{
  "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

CampDescripcióExemple
idClau primària1
comarca_nameNom de la comarcaVallès Occidental
comarca_codeCodi de la comarca40

Exemple de resposta:

json
{
  "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.

CampDescripcióExemple
comarca.comarca_nameNom de la comarcaBaix Llobregat
comarca.comarca_codeCodi de la comarca11
indicator.indicator_idCodi de l'indicador1.4.2
indicator.nameNom de l'indicadorProporció de persones amb discapacitat que reben una pensió
valueValor principal (o numerador)2145
value2Valor secundari (denominador), si aplica74013
subindicatorÍndex de subindicador, si l'indicador en ténull
yearAny de la dada2023

Exemple de resposta:

json
{
  "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.

CampDescripcióExemple
province.province_codeCodi de la província8
province.province_nameNom de la provínciaBarcelona
indicator.indicator_idCodi de l'indicador1.4.2
indicator.nameNom de l'indicadorProporció de persones amb discapacitat que reben una pensió
valueValor principal (o numerador)17655
value2Valor secundari (denominador), si aplica501657
subindicatorÍndex de subindicador, si l'indicador en ténull
yearAny de la dada2023

Exemple de resposta:

json
{
  "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.).

CampDescripcióExemple
aggregation.nameNom de l'agrupacióRural
aggregation.slugIdentificador curt de l'agrupaciórural
aggregation.groupFamília de l'agrupacióruralitat
indicator.indicator_idCodi de l'indicador1.2.3
indicator.nameNom de l'indicadorNombre de socis de cooperatives per 1.000 habitants
valueValor principal (o numerador)712
value2Valor secundari (denominador), si aplica69622
subindicatorÍndex de subindicador, si l'indicador en ténull
yearAny de la dada2025

Exemple de resposta:

json
{
  "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.

CampDescripcióExemple
idClau primària1
target.sdgNúmero de l'ODS de la fita (1–17)1
target.target_idCodi de la fita1.2
indicator_idCodi de l'indicador1.2.1
nameNom de l'indicador% Població amb ingressos < 60%
signtrue = més alt és millor; false = més baix és millorfalse
unitUnitat de mesura internapercent
scaleFactor d'escala heretat (no s'usa al backend)1
weightPes de l'indicador per al càlcul de l'ODS sintètic (0–100)45
calculationEstratègia de càlculsimple
dimension_weightPes de la dimensió per al càlcul sintètic (0–100)0
municipalityCountNombre de municipis amb dades per a l'indicador246
yearCountNombre d'anys amb dades disponibles9
lastYearAvailableÚltim any amb dades2023
mostRecentDateData de la darrera actualització de dades2026-06-02T13:04:32+00:00

Exemple de resposta:

json
{
  "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: truecom més alt, millor (p. ex. Renda mediana: un valor més gran és una situació més bona).
  • sign: falsecom 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.

CampDescripcióExemple
idClau primària20
sdgNúmero de l'ODS (1–17)1
target_idCodi de la fita1.1
target_nameNom descriptiu de la fitaReduir la pobresa extrema
indicators[].indicator_idCodi de cada indicador de la fita1.1.1
indicators[].nameNom de l'indicador% Població amb ingressos < 40%
indicators[].signSentit de l'indicador: true = més alt és millor; false = més baix és millortrue
indicators[].unitUnitat internapercent
indicators[].descriptionDescripció de l'indicadorPercentatge de població…
indicators[].weightPes per al càlcul sintètic0
indicators[].calculationEstratègia de càlculsimple
indicators[].dimension_weightPes de dimensió20

Exemple de resposta:

json
{
  "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.

CampDescripcióExemple
idClau primària1
nameNom de l'agrupacióRural
slugIdentificador curtrural
groupFamília de l'agrupació (ruralitat, ubicacio, regional-flag, territorial-region)ruralitat

Exemple de resposta:

json
{ "id": 1, "name": "Rural", "slug": "rural", "group": "ruralitat" }

Població — /api/populations

Sèrie històrica de població per municipi i any.

CampDescripcióExemple
municipality.municipality_nameNom del municipiPolinyà
municipality.municipality_codeCodi INE de 5 dígits08167
population_countHabitants aquell any8555
yearAny de la dada2024

Exemple de resposta:

json
{
  "municipality": { "municipality_name": "Polinyà", "municipality_code": "08167" },
  "population_count": 8555,
  "year": 2024
}

Pressupostos — /api/budgets

Despesa pressupostària per municipi, programa i any.

CampDescripcióExemple
yearAny del pressupost2010
valueImport (€)759806
programCodi de programa pressupostari1
municipalityURI del municipi/api/municipalities/283

Exemple de resposta:

json
{ "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]=asc

Filtres disponibles per recurs (els més usats):

RecursFiltres SearchFilterFiltres OrderFilter
municipality_valuesmunicipality.id, municipality.municipality_code, municipality.municipality_code_6, municipality.comarca.comarca_code, municipality.aggregations.slug, indicator.indicator_id, indicator.target.sdg, yearyear, value
municipalitiesaggregations.slugmunicipality_name, municipality_code_6
comarca_valuescomarca.id, comarca.comarca_code, indicator.indicator_id, indicator.target.target_id, indicator.id, year
province_valuesindicator.indicator_id, indicator.target.target_id, indicator.id, year
aggregation_valuesaggregation, aggregation.slug, indicator, indicator.indicator_id, year
aggregationsgroup, slug
targetssdg
budgetsmunicipality.*, program, yearprogram
populationsyear, 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).

EndpointMètodeDescripció
/api/synthetic-sdgGETPuntuació sintètica per ODS (vegeu ODS sintètics)
/api/sdg-indicatorsGETValors en brut dels indicadors d'un ODS
/api/municipalities-under-weightGETEntitats amb cobertura d'indicadors insuficient
/api/labels-hierarchyGETEtiquetes/textos de la UI (jerarquia)
/api/labels-importPOSTDesa etiquetes editades (requereix JWT)
/api/etl/{indicator_id}POSTDispara la importació ETL d'un indicador via HTTP
/export/csvGETExporta valors a CSV
/export/indicatorsGETExporta el catàleg d'indicadors a CSV
/api/loginPOSTAutenticació 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àmetreDescripcióExemple
typeTipus d'entitat: municipality (per defecte), comarca, aggregationcomarca
municipality_codeCodi INE de 5 dígits (per a type=municipality)08019
comarca_codeCodi de comarca (per a type=comarca)11
aggregation_slugSlug de l'agrupació (per a type=aggregation)rural
sdgFiltra a un ODS concret (opcional)3
globalSi és true, retorna també les puntuacions per dimensió1

Camps de resposta:

CampDescripcióExemple
sdgNúmero de l'ODS1
codeCodi de l'entitat080193
nameNom de l'entitatBarcelona
populationPoblació (només per a municipis; null per a comarca/agrupació)1731649
valuePuntuació sintètica de l'ODS (0–100)49.74
municipality_code_6Codi de 6 dígits (només per a municipis)080193
municipality_nameNom del municipi (només per a municipis)Barcelona

Exemple de resposta (type=municipality):

json
[
  { "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àmetreDescripcióExemple
sdgObligatori. Número de l'ODS1
municipality.municipality_codeFiltra per municipi (opcional)08019

Camps de resposta:

CampDescripcióExemple
valueValor de l'indicador10.5
value2Valor secundari (denominador), si aplicanull
yearAny de la dada2023
municipality_codeCodi INE de 5 dígits08001
municipality_nameNom del municipiAbrera
municipality_code_6Codi INE de 6 dígits080018
populationPoblació del municipi13227
indicator_idCodi de l'indicador1.2.1
sdgNúmero de l'ODS1

Exemple de resposta:

json
[
  {
    "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:

json
{
  "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 ODS 117 o un codi d'indicador X.X.X), municipality i year (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:

json
{ "status": "Indicator 1.2.1 imported successfully" }

Resposta d'error (p. ex. indicador no trobat):

json
{ "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:

json
{ "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.

Publicat sota llicència MIT