Alfil Electoral API

The Electoral API from Alfil — 4 operation(s) for electoral.

Operations 4

GET /v1/electoral/resultados Resultados electorales #
GET /v1/electoral/desglose Desglose geográfico de una elección #
GET /v1/electoral/puestos Puestos de votación geolocalizados #
GET /v1/electoral/censo Censo electoral por edad y sexo #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/alfil-co:alfil-co-electoral-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

alfil-co-electoral-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Alfil Electoral API
  version: v1
  description: API pública de transparencia política de Alfil. Read-only. Cada respuesta incluye su fuente oficial y fecha de corte. Ver la política de datos personales en ADR-020.
servers:
- url: https://api.alfil.co
security:
- oauth2:
  - buscar:read
tags:
- name: Electoral
paths:
  /v1/electoral/resultados:
    get:
      summary: Resultados electorales
      description: Drill-down dept→mun→puesto→mesa. Etiqueta preconteo|escrutinio siempre presente.
      tags:
      - Electoral
      parameters:
      - in: query
        name: cursor
        schema:
          default: 0
          type: integer
          minimum: 0
          maximum: 9007199254740991
        description: Cursor de paginación (posición del ranking desde la que continuar)
      - in: query
        name: limit
        schema:
          default: 25
          type: integer
          minimum: 1
          maximum: 100
        description: Máximo de resultados (1-100, default 25)
      - in: query
        name: eleccion
        schema:
          type: string
        description: Código público {tipo}-{año}[-{ámbito}] (p. ej. presidencia-2026, presidencia-2026-2v, camara-2026-antioquia, alcalde-2023-medellin) o id interno numérico
        required: true
      - in: query
        name: departamento
        schema:
          type: string
        description: Nombre de departamento (accent-insensitive); ignorado si el código ya trae ámbito departamental
      - in: query
        name: municipio
        schema:
          type: string
        description: Nombre de municipio + departamento resuelto; ambiguo → error accionable
      - in: query
        name: zona
        schema:
          type: string
        description: Nombre de zona/localidad (hoy solo localidades de Bogotá)
      - in: query
        name: puesto
        schema:
          type: string
        description: Nombre/código de puesto de votación, acotado al municipio resuelto; ambiguo → no se resuelve (queda en el nivel anterior)
      - in: query
        name: orden
        schema:
          default: votos_desc
          type: string
          enum:
          - votos_desc
        description: Orden de los resultados (hoy solo votos_desc, el único que soporta el RPC)
      - in: query
        name: partido
        schema:
          type: string
        description: Nombre del partido para filtrar (case-insensitive; no es un slug real pese al nombre del parámetro RPC)
      responses:
        '200':
          description: Resultados por ámbito
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResultadosElectorales'
        '401':
          description: Token faltante, expirado o de emisor inesperado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Scope insuficiente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Cuota agotada o rate limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      operationId: getV1ElectoralResultados
      x-operation-id-source: derived
  /v1/electoral/desglose:
    get:
      summary: Desglose geográfico de una elección
      description: Votos totales (o de un candidato) por cada hijo geográfico del ámbito consultado (dept→mun→zona/puesto→mesa).
      tags:
      - Electoral
      parameters:
      - in: query
        name: eleccion
        schema:
          type: string
        description: Código público {tipo}-{año}[-{ámbito}] (p. ej. presidencia-2026, camara-2026-antioquia) o id interno numérico
        required: true
      - in: query
        name: departamento
        schema:
          type: string
        description: Nombre de departamento (accent-insensitive); ignorado si el código ya trae ámbito departamental
      - in: query
        name: municipio
        schema:
          type: string
        description: Nombre de municipio + departamento resuelto; ambiguo → error accionable
      - in: query
        name: zona
        schema:
          type: string
        description: Nombre de zona/localidad (hoy solo localidades de Bogotá); alias de "localidad"
      - in: query
        name: localidad
        schema:
          type: string
        description: Alias de "zona" — localidades de Bogotá
      - in: query
        name: candidato
        schema:
          type: string
          pattern: ^[1-9]\d{5,11}$
        description: Cédula del candidato para desglosar SUS votos por hijo geográfico (en vez del total). Cruce legítimo de control social (ADR-020).
      - in: query
        name: orden
        schema:
          default: votos_desc
          type: string
          enum:
          - votos_desc
          - votos_asc
        description: votos_desc (default) o votos_asc. Combinado con "candidato", votos_asc responde "¿dónde debería fortalecerme?" (los hijos donde el candidato sacó menos votos primero).
      responses:
        '200':
          description: Desglose por hijo geográfico
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ElectoralDesglose'
        '401':
          description: Token faltante, expirado o de emisor inesperado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Scope insuficiente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Cuota agotada o rate limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      operationId: getV1ElectoralDesglose
      x-operation-id-source: derived
  /v1/electoral/puestos:
    get:
      summary: Puestos de votación geolocalizados
      description: Puestos de un municipio con coordenadas, para razonamiento espacial y mapas.
      tags:
      - Electoral
      parameters:
      - in: query
        name: eleccion
        schema:
          type: string
        description: Código público {tipo}-{año}[-{ámbito}] (p. ej. presidencia-2026, alcalde-2023-medellin) o id interno numérico
        required: true
      - in: query
        name: departamento
        schema:
          type: string
        description: Departamento del municipio (accent-insensitive). Requerido salvo que el código de elección ya lo traiga embebido (p. ej. alcalde-2023-medellin)
      - in: query
        name: municipio
        schema:
          type: string
        description: Nombre del municipio (requerido) + departamento resuelto
        required: true
      - in: query
        name: candidato
        schema:
          type: string
          pattern: ^[1-9]\d{5,11}$
        description: Cédula del candidato para agregar votos_candidato por puesto. Cruce legítimo de control social (ADR-020).
      - in: query
        name: partido
        schema:
          type: string
        description: Slug del partido (catálogo de Alfil) para agregar votos_partido por puesto
      responses:
        '200':
          description: Puestos con geolocalización
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ElectoralMapa'
        '401':
          description: Token faltante, expirado o de emisor inesperado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Scope insuficiente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Cuota agotada o rate limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      operationId: getV1ElectoralPuestos
      x-operation-id-source: derived
  /v1/electoral/censo:
    get:
      summary: Censo electoral por edad y sexo
      description: Votantes habilitados de una elección por sexo y, cuando la fuente lo trae, por rango etario, a nivel nacional/departamental/municipal/puesto. Cita el radicado oficial (RNEC) o DIVIPOL como fuente.
      tags:
      - Electoral
      parameters:
      - in: query
        name: eleccion
        schema:
          type: string
        description: Código público {tipo}-{año}[-{ámbito}] (p. ej. presidencia-2026, camara-2026-antioquia) o id interno numérico
        required: true
      - in: query
        name: geografia
        schema:
          type: string
          pattern: ^\d{2}(\d{3})?$
        description: Código DIVIPOLA del departamento (2 dígitos) o municipio (5 dígitos) a consultar; obligatorio salvo nivel=nacion
      - in: query
        name: nivel
        schema:
          default: nacion
          type: string
          enum:
          - nacion
          - departamento
          - municipio
          - puesto
        description: Nivel de agregación del censo
      - in: query
        name: cursor
        schema:
          default: 0
          type: integer
          minimum: 0
          maximum: 9007199254740991
        description: Posición desde la que continuar el desglose `filas` (para recuperar el resto cuando la respuesta anterior trae truncado=true / pagina.has_more=true)
      responses:
        '200':
          description: Censo por sexo y edad
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ElectoralCenso'
        '401':
          description: Token faltante, expirado o de emisor inesperado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Scope insuficiente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Cuota agotada o rate limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      operationId: getV1ElectoralCenso
      x-operation-id-source: derived
components:
  schemas:
    ElectoralCenso:
      type: object
      properties:
        eleccion:
          type: object
          properties:
            codigo:
              type: string
            nombre:
              type: string
          required:
          - codigo
          - nombre
          additionalProperties: false
        fecha:
          type: string
          description: Fecha de corte del censo (fecha de la elección), ISO 8601
        total:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        por_sexo:
          type: object
          properties:
            mujeres:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            hombres:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
          required:
          - mujeres
          - hombres
          additionalProperties: false
        por_edad:
          anyOf:
          - type: array
            items:
              $ref: '#/components/schemas/CensoEdad'
          - type: 'null'
          description: null cuando la fuente solo trae la partición por sexo (DIVIPOL)
        filas:
          type: array
          items:
            $ref: '#/components/schemas/CensoFila'
        truncado:
          type: boolean
          description: true cuando esta página no trae el resto del desglose crudo (equivalente a pagina.has_more); total/por_sexo/por_edad siempre reflejan TODAS las filas del censo, nunca solo la página devuelta
        pagina:
          $ref: '#/components/schemas/Page'
        fuente:
          $ref: '#/components/schemas/CensoFuente'
      required:
      - eleccion
      - fecha
      - total
      - por_sexo
      - por_edad
      - filas
      - truncado
      - pagina
      - fuente
      additionalProperties: false
    ResultadosElectorales:
      type: object
      properties:
        eleccion:
          type: object
          properties:
            codigo:
              type: string
            nombre:
              type: string
          required:
          - codigo
          - nombre
          additionalProperties: false
        ambito:
          $ref: '#/components/schemas/AmbitoGeografico'
        resultados:
          type: array
          items:
            $ref: '#/components/schemas/ResultadoCandidato'
        page:
          $ref: '#/components/schemas/Page'
        fuente:
          $ref: '#/components/schemas/Fuente'
      required:
      - eleccion
      - ambito
      - resultados
      - page
      - fuente
      additionalProperties: false
    ResultadoCandidato:
      type: object
      properties:
        candidato:
          type: string
        partido:
          type: string
        votos:
          type: string
          description: Votos (bigint como string)
          example: '48213'
        porcentaje:
          type: number
        ranking:
          description: Posición en el ranking (bigint como string)
          example: '1'
          type: string
        is_elected:
          description: Si el candidato resultó electo
          type: boolean
      required:
      - candidato
      - partido
      - votos
      additionalProperties: false
    Page:
      type: object
      properties:
        cursor:
          anyOf:
          - type: string
          - type: 'null'
          description: Cursor opaco de la siguiente página; null si no hay más
        has_more:
          type: boolean
          description: Indica si existen más resultados
      required:
      - cursor
      - has_more
      additionalProperties: false
      description: Paginación por cursor opaco (no offset)
    ElectoralDesglose:
      type: object
      properties:
        eleccion:
          type: object
          properties:
            codigo:
              type: string
            nombre:
              type: string
          required:
          - codigo
          - nombre
          additionalProperties: false
        ambito:
          $ref: '#/components/schemas/AmbitoGeografico'
        candidato:
          description: Presente solo si se filtró por candidato — "votos" en cada hijo son los de este candidato
          type: object
          properties:
            cedula:
              type: string
            nombre:
              type: string
          required:
          - cedula
          - nombre
          additionalProperties: false
        orden:
          type: string
          enum:
          - votos_desc
          - votos_asc
        hijos:
          type: array
          items:
            $ref: '#/components/schemas/ElectoralDesgloseHijo'
        fuente:
          $ref: '#/components/schemas/Fuente'
      required:
      - eleccion
      - ambito
      - orden
      - hijos
      - fuente
      additionalProperties: false
    CensoEdad:
      type: object
      properties:
        rango:
          type: string
          description: Rango etario (p. ej. 18-20, 60+)
        mujeres:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        hombres:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
      - rango
      - mujeres
      - hombres
      additionalProperties: false
    ElectoralDesgloseHijo:
      type: object
      properties:
        nombre:
          type: string
        codigo:
          anyOf:
          - type: string
          - type: 'null'
          description: Código interno del hijo (no siempre un código DIVIPOLA oficial)
        nivel:
          type: string
          enum:
          - departamento
          - municipio
          - zona
          - puesto
          - mesa
          description: Nivel geográfico del hijo — lo determina el RPC según qué tan profundo esté el ámbito consultado
        votos:
          type: string
          description: Votos (bigint como string)
          example: '48213'
        tiene_hijos:
          type: boolean
          description: Si este hijo admite más drill-down (otra llamada más profunda)
      required:
      - nombre
      - codigo
      - nivel
      - votos
      - tiene_hijos
      additionalProperties: false
    Referencia:
      type: object
      properties:
        tipo:
          type: string
          enum:
          - pagina_alfil
          - registro_oficial
          - documento_oficial
          - coleccion_oficial
        titulo:
          type: string
        url:
          type: string
          pattern: ^[hH][tT][tT][pP][sS]:\/\/[^/?#@]+(?:[/?#].*)?$
          format: uri
        proveedor:
          type: string
        id_externo:
          type: string
      required:
      - tipo
      - titulo
      - url
      - proveedor
      additionalProperties: false
      description: Enlace HTTPS navegable a Alfil o a una fuente oficial
    CensoFuente:
      type: object
      properties:
        tipo:
          type: string
          enum:
          - rnec_potencial_etario
          - divipol
        referencia:
          anyOf:
          - type: string
          - type: 'null'
          description: Radicado de la solicitud Ley 1712 cuando la fuente es rnec_potencial_etario; null para divipol
      required:
      - tipo
      - referencia
      additionalProperties: false
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Código de error estable (ASCII)
              example: quota_exceeded
            message:
              type: string
            metric:
              type: string
            resetAt:
              type: string
          required:
          - code
          additionalProperties: false
      required:
      - error
      additionalProperties: false
    AmbitoGeografico:
      type: object
      properties:
        nivel:
          type: string
          enum:
          - nacional
          - departamento
          - municipio
          - zona
          - puesto
          - mesa
        departamento:
          type: object
          properties:
            divipola:
              type: string
            nombre:
              type: string
          required:
          - divipola
          - nombre
          additionalProperties: false
        municipio:
          type: object
          properties:
            divipola:
              type: string
            nombre:
              type: string
          required:
          - divipola
          - nombre
          additionalProperties: false
        zona:
          description: Zona/localidad; `divipola` es el id interno, NO un código DIVIPOLA oficial
          type: object
          properties:
            divipola:
              type: string
            nombre:
              type: string
          required:
          - divipola
          - nombre
          additionalProperties: false
        puesto:
          description: Puesto de votación; `divipola` es el id interno, NO un código DIVIPOLA oficial
          type: object
          properties:
            divipola:
              type: string
            nombre:
              type: string
          required:
          - divipola
          - nombre
          additionalProperties: false
      required:
      - nivel
      additionalProperties: false
      description: Ámbito consultado, ecoado con código DIVIPOLA + nombre
    PuestoMapa:
      type: object
      properties:
        id:
          type: string
        nombre:
          type: string
        direccion:
          anyOf:
          - type: string
          - type: 'null'
        lat:
          anyOf:
          - type: number
          - type: 'null'
        lng:
          anyOf:
          - type: number
          - type: 'null'
        votos_totales:
          type: string
          description: Votos totales del puesto (bigint como string)
        votos_candidato:
          description: Presente solo si se filtró por candidato
          type: string
        votos_partido:
          description: Presente solo si se filtró por partido
          type: string
        mesas:
          anyOf:
          - type: number
          - type: 'null'
        habilitados:
          anyOf:
          - type: number
          - type: 'null'
          description: Censo electoral habilitado en el puesto
      required:
      - id
      - nombre
      - direccion
      - lat
      - lng
      - votos_totales
      - mesas
      - habilitados
      additionalProperties: false
    Fuente:
      type: object
      properties:
        nombre:
          type: string
          description: Fuente oficial del dato
          example: SECOP II — datos.gov.co
        url:
          description: URL de la fuente oficial
          type: string
        corte:
          type: string
          description: Fecha de corte del dato (ISO 8601)
          example: '2026-07-09'
        licencia:
          description: Licencia de la fuente
          example: CC BY-SA 4.0
          type: string
      required:
      - nombre
      - corte
      additionalProperties: false
      description: 'Proveniencia: fuente oficial y fecha de corte (atribución Ley 1712)'
    CensoFila:
      type: object
      properties:
        codigo:
          anyOf:
          - type: string
          - type: 'null'
          description: Código DIVIPOLA de la fila (null a nivel nación)
        rango:
          type: string
          description: Rango etario, o 'total' cuando la fuente solo trae sexo
        sexo:
          type: string
          enum:
          - F
          - M
        habilitados:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
      - codigo
      - rango
      - sexo
      - habilitados
      additionalProperties: false
    ElectoralMapa:
      type: object
      properties:
        eleccion:
          type: object
          properties:
            codigo:
              type: string
            nombre:
              type: string
          required:
          - codigo
          - nombre
          additionalProperties: false
        municipio:
          type: object
          properties:
            divipola:
              type: string
            nombre:
              type: string
          required:
          - divipola
          - nombre
          additionalProperties: false
        candidato:
          type: object
          properties:
            cedula:
              type: string
            nombre:
              type: string
          required:
          - cedula
          - nombre
          additionalProperties: false
        partido:
          type: object
          properties:
            slug:
              type: string
            nombre:
              type: string
          required:
          - slug
          - nombre
          additionalProperties: false
        puestos:
          type: array
          items:
            $ref: '#/components/schemas/PuestoMapa'
        referencias:
          type: array
          items:
            $ref: '#/components/schemas/Referencia'
          description: Enlaces navegables a Alfil derivados del filtro aplicado (p. ej. el perfil del partido); vacío si el mapa no fue filtrado por una entidad navegable
        fuente:
          $ref: '#/components/schemas/Fuente'
      required:
      - eleccion
      - municipio
      - puestos
      - referencias
      - fuente
      additionalProperties: false
  securitySchemes:
    oauth2:
      type: oauth2
      description: OAuth 2.1 con la cuenta Alfil (Supabase Auth como authorization server).
      flows:
        authorizationCode:
          authorizationUrl: https://api.alfil.co/oauth/authorize
          tokenUrl: https://api.alfil.co/oauth/token
          scopes:
            buscar:read: Búsqueda federada
            politicos:read: Perfiles y búsqueda de políticos
            partidos:read: Perfiles de partidos
            contratos:read: Contratación SECOP
            electoral:read: Resultados electorales
            congreso:read: Actividad legislativa
            finanzas:read: Finanzas públicas territoriales
            geografias:read: Catálogo DIVIPOLA