Saltar al contenido

Consumir una API REST con POST y OAuth en Power BI

Ilustración oscura de un servidor en la nube conectado a una app con un candado y una llave representando OAuth

Escrito por

en

,

Consumir una API REST con POST y OAuth en Power BI

TL;DR: Power BI puede consumir APIs REST con POST y OAuth usando Web.Contents en Lenguaje M. El flujo tiene dos llamadas: primero un POST al endpoint de token con las credenciales en Base64 en el encabezado Authorization: Basic, que devuelve un access_token; luego un segundo POST (o GET) al endpoint de datos con Authorization: Bearer <token>. La clave es pasar el cuerpo con Content y declarar Content-Type en Headers.


No hemos podido validar tu suscripción.
Tu PDF va en camino — revisa tu correo

Tu guía de Power Query gratis

Conectar Power BI a un origen con autenticación moderna es uno de los saltos que separa al analista que «carga archivos» del que integra sistemas. El conector gráfico de Power BI maneja bien las APIs simples con GET, pero en cuanto aparece un POST con OAuth, la interfaz se queda corta y hay que bajar al Lenguaje M. No es casualidad que el hilo original sobre este tema acumule más de 84.000 vistas: es un muro con el que choca casi todo el mundo tarde o temprano.

Este artículo reconstruye el flujo completo, del token a los datos, con código que puedes adaptar a tu propia API.

¿Qué es el flujo OAuth de tipo client credentials?

OAuth no envía tu usuario y contraseña en cada petición. En su lugar, intercambias unas credenciales de aplicación (client_id y client_secret) por un token de acceso temporal, y usas ese token para autorizar las llamadas siguientes.

El patrón más común en integraciones servidor-a-servidor es client credentials:

  1. Codificas client_id:client_secret en Base64.
  2. Haces un POST al endpoint de token con ese valor en el encabezado Authorization: Basic.
  3. La API responde con un JSON que contiene access_token.
  4. Usas Authorization: Bearer <access_token> en las peticiones de datos.

¿Cuándo necesitas hacerlo en M y no con el conector?

  • La API requiere método POST para devolver datos (no solo GET).
  • La autenticación es OAuth client credentials u otra que el conector no expone.
  • Necesitas enviar un cuerpo JSON con parámetros (filtros, rangos de fechas, paginación).
  • Vas a parametrizar el origen para reutilizarlo en varios reportes.

¿Cómo se hace paso a paso?

Paso 1: codificar las credenciales en Base64

El encabezado Basic espera client_id:client_secret en Base64. M lo hace sin salir de Power Query:

let
    ClientId = "TU_CLIENT_ID",
    ClientSecret = "TU_CLIENT_SECRET",
    Credenciales = ClientId & ":" & ClientSecret,
    Base64 = Binary.ToText(
        Text.ToBinary(Credenciales, BinaryEncoding.Base64),
        BinaryEncoding.Base64
    )
in
    Base64

Nota de seguridad: no escribas las credenciales en claro en producción. Usa parámetros de Power Query y configura el origen como privado en el servicio.

Paso 2: obtener el token con un POST

Web.Contents hace POST cuando le pasas Content. El cuerpo se codifica como binario:

let
    ClientId = "TU_CLIENT_ID",
    ClientSecret = "TU_CLIENT_SECRET",
    Base64 = Binary.ToText(
        Text.ToBinary(ClientId & ":" & ClientSecret, BinaryEncoding.Base64),
        BinaryEncoding.Base64
    ),
    RespuestaToken = Json.Document(
        Web.Contents(
            "https://api.ejemplo.com/oauth2/token",
            [
                Headers = [
                    #"Authorization" = "Basic " & Base64,
                    #"Content-Type" = "application/x-www-form-urlencoded"
                ],
                Content = Text.ToBinary("grant_type=client_credentials")
            ]
        )
    ),
    Token = RespuestaToken[access_token]
in
    Token

Tres detalles que rompen la consulta si los omites: el espacio tras Basic, el Content-Type correcto para el endpoint de token, y leer la respuesta con Json.Document.

Paso 3: pedir los datos con el token

Con el token en mano, el segundo POST envía un cuerpo JSON y autoriza con Bearer:

let
    Datos = Json.Document(
        Web.Contents(
            "https://api.ejemplo.com/v1/ventas",
            [
                Headers = [
                    #"Authorization" = "Bearer " & Token,
                    #"Content-Type" = "application/json"
                ],
                Content = Json.FromValue(
                    [ fechaInicio = "2026-01-01", fechaFin = "2026-06-30" ]
                )
            ]
        )
    ),
    Tabla = Table.FromRecords( Datos[resultados] )
in
    Tabla

Json.FromValue convierte un record M directamente en cuerpo JSON, sin escribir la cadena a mano.

Paso 4: unir todo en una sola consulta

En producción conviene encadenar token y datos en un único let para que el token se obtenga fresco en cada actualización:

let
    Base64 = Binary.ToText(
        Text.ToBinary(ClientId & ":" & ClientSecret, BinaryEncoding.Base64),
        BinaryEncoding.Base64
    ),
    Token = Json.Document(
        Web.Contents("https://api.ejemplo.com/oauth2/token", [
            Headers = [ #"Authorization" = "Basic " & Base64,
                        #"Content-Type" = "application/x-www-form-urlencoded" ],
            Content = Text.ToBinary("grant_type=client_credentials")
        ])
    )[access_token],
    Datos = Json.Document(
        Web.Contents("https://api.ejemplo.com/v1/ventas", [
            Headers = [ #"Authorization" = "Bearer " & Token,
                        #"Content-Type" = "application/json" ],
            Content = Json.FromValue([ fechaInicio = "2026-01-01" ])
        ])
    ),
    Tabla = Table.FromRecords( Datos[resultados] )
in
    Tabla

Errores comunes

Síntoma Causa Solución
Error 401 al pedir el token Base64 mal formado o falta el espacio tras Basic Revisar codificación y "Basic " & Base64
Falla la actualización en el Servicio URL dinámica no permitida por privacidad Usar RelativePath y Query en Web.Contents
Error 415 Unsupported Media Type Content-Type incorrecto Ajustar a lo que exige cada endpoint
El token caduca a media carga Tabla grande, token de vida corta Encadenar token y datos en la misma consulta
Web.Contents no hace POST Falta la opción Content Añadir Content = ... fuerza el método POST

Conclusión

Consumir una API REST con POST y OAuth en Power BI es totalmente factible sin pasarelas externas ni scripts intermedios: todo cabe en Lenguaje M con Web.Contents. Dominar este patrón te abre la puerta a integrar CRMs, ERPs y servicios en la nube directamente en tus modelos.

Si quieres llevar tu Power Query al nivel de integrar APIs, JSON y orígenes web complejos con soltura, este curso está hecho para eso:

Power BI: Power Query Limpiar y extraer Datos con Lenguaje MUdemy
Power Query

Power BI: Power Query Limpiar y extraer Datos con Lenguaje M

★ 4.6(1100 estudiantes)
$54.99

Fuente: hilo del foro oficial de Microsoft Fabric con más de 84.000 vistas, solución verificada por la comunidad.

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *