Si vas a conectar una web, un CRM o un informe con Business Central, la primera decisión es por qué puerta entrar. Hay tres, las tres hablan OData v4 y se parecen mucho, pero no son intercambiables: una de ellas, además, tiene fecha de caducidad para buena parte de sus usos.
En este artículo te explico las tres, cómo autenticarte y las consultas que vas a usar a diario.
Las tres formas de leer y escribir datos
| Puerta | Qué es | Cuándo usarla |
|---|---|---|
| API estándar v2.0 | Endpoints que publica Microsoft para clientes, artículos, pedidos, facturas... | Siempre que cubra lo que necesitas: es estable y está versionada. |
| APIs propias | Páginas o consultas de tipo API que programas en una extensión AL |
Cuando necesitas campos o tablas propias, o datos que la API estándar no expone. |
| Servicios web OData | Páginas y consultas publicadas desde la página Servicios web | Casos puntuales. Para páginas de Microsoft, con los días contados (lo vemos abajo). |
La diferencia de fondo: una API es un contrato. Microsoft no cambia la API v2.0 sin versionarla, y tus APIs propias solo cambian cuando tú quieres. Una página publicada como servicio web es una pantalla, y las pantallas cambian en cada versión sin que eso se considere un cambio que rompa nada.
Las URLs
Todas cuelgan del mismo dominio. Necesitas el id del tenant (o su dominio), el nombre del entorno (production, sandbox...) y la empresa:
# API estándar v2.0
https://api.businesscentral.dynamics.com/v2.0/{tenant}/{entorno}/api/v2.0/companies({companyId})/customers
# API propia: publisher, grupo y versión de tu página API
https://api.businesscentral.dynamics.com/v2.0/{tenant}/{entorno}/api/{publisher}/{grupo}/v1.0/companies({companyId})/{entitySetName}
# Servicio web OData publicado
https://api.businesscentral.dynamics.com/v2.0/{tenant}/{entorno}/ODataV4/Company('{nombre}')/{nombreServicio}
El companyId es un GUID. Lo obtienes con una primera llamada a .../api/v2.0/companies, que devuelve todas las empresas del entorno con su id.
Autenticación: OAuth 2.0 y nada más
Desde el 1 de octubre de 2022, Business Central online no acepta las claves de acceso a servicios web (la antigua autenticación básica con usuario y clave). La única opción es OAuth 2.0 con Microsoft Entra ID.
Para una integración de servidor a servidor (tu backend hablando con Business Central, sin usuario delante), el flujo es client credentials:
- Registra una aplicación en Microsoft Entra ID (portal de Azure) y créale un secreto o, mejor, un certificado.
- En Permisos de API, añade Dynamics 365 Business Central con el permiso de aplicación
API.ReadWrite.Ally concede el consentimiento de administrador. - En Business Central, abre la página Aplicaciones de Microsoft Entra, da de alta el id de cliente de la aplicación y asígnale solo los conjuntos de permisos que necesite (Business Central ni siquiera permite asignar
SUPERa una aplicación). - Pide el token y úsalo en cada llamada:
const res = await fetch(`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, {
method: 'POST',
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: 'https://api.businesscentral.dynamics.com/.default'
})
});
const { access_token, expires_in } = await res.json();
const customers = await fetch(`${baseUrl}/companies(${companyId})/customers`, {
headers: { Authorization: `Bearer ${access_token}` }
}).then(r => r.json());
Guarda el token en caché hasta que caduque (expires_in, en segundos) en lugar de pedir uno nuevo en cada llamada. Y todo esto vive en tu servidor: el secreto nunca debe llegar al navegador.
Consultas que vas a usar a diario
La API habla OData v4, así que filtras, eliges campos y expandes relaciones con parámetros en la URL:
GET .../companies({companyId})/salesOrders
?$filter=status eq 'Open' and orderDate ge 2026-01-01
&$select=number,customerName,orderDate,totalAmountIncludingTax
&$expand=salesOrderLines
&$orderby=orderDate desc
&$top=50
$filter: filtra en el servidor. No te traigas 20.000 registros para quedarte con 10.$select: pide solo los campos que vas a usar. Las respuestas pesan menos y llegan antes.$expand: trae las líneas con la cabecera en una sola llamada.- Paginación: si hay más resultados, la respuesta incluye
@odata.nextLink. Síguelo hasta que no aparezca. - Sincronización incremental: casi todas las entidades tienen
lastModifiedDateTime. Filtra por la fecha de tu última sincronización ($filter=lastModifiedDateTime gt 2026-10-01T00:00:00Z) en lugar de leerlo todo cada vez. - Ojo con
status: los valores de la API no coinciden con los de la pantalla. Un pedido Abierto en Business Central sale comoDraft, yOpenes un pedido ya Lanzado (o pendiente de prepago). El filtro del ejemplo trae, por tanto, los pedidos lanzados.
Para modificar o borrar (PATCH, DELETE), Business Central exige la cabecera If-Match con el @odata.etag del registro que leíste. Es control de concurrencia: si alguien lo ha cambiado entretanto, la llamada falla en lugar de pisar su cambio.
Límites: el 429 te va a llegar
Business Central online limita las peticiones por usuario (y una aplicación de Entra cuenta como un usuario más):
| Límite | Valor | Si lo superas |
|---|---|---|
| Peticiones en una ventana de 5 minutos | 6.000 | 429 Too Many Requests |
| Peticiones procesándose a la vez | 5 (el resto espera en cola) | 503 si espera más de 8 minutos |
| Peticiones simultáneas, en proceso y en cola | 100 | 429 |
| Registros por respuesta | 20.000 | 413 |
Operaciones en un $batch |
100 | - |
| Duración de una petición | 8 minutos | 408 |
En la práctica: implementa reintentos con espera creciente para 429 y 503, usa $batch cuando tengas que mandar muchas operaciones pequeñas y no hagas lecturas completas cada pocos minutos. Si una integración es muy intensiva, Microsoft recomienda repartir la carga entre varios usuarios o aplicaciones.
Lo que cambia en 2026 y 2027
Esto es lo que más integraciones va a romper en los próximos meses:
- SOAP en páginas de Microsoft: desde la versión 29 (2026 release wave 2, la actual) ya no se pueden publicar páginas de Microsoft como servicio SOAP.
- OData en páginas de Microsoft: a partir de la versión 30 (2027 release wave 1, primavera de 2027) tampoco se podrán publicar como servicio OData. Si tu integración lee, por ejemplo, la página Ficha cliente publicada en Servicios web, dejará de funcionar.
- API v1.0: se retiró en la versión 28. Si algo sigue llamando a
/api/v1.0/, ya está roto o lo estará al actualizar. - Delta links: retirados desde la versión 24. Para saber qué ha cambiado, usa webhooks o
lastModifiedDateTime.
Microsoft lo justifica así: una página es una pantalla, no una API, y cambiarla no se considera un cambio incompatible. Las alternativas son pasar a la API v2.0, o copiar la página a una extensión propia o, mejor, crear una API propia.
Una API propia en AL
Cuando la API estándar no trae lo que necesitas, una página de tipo API en una extensión es la solución limpia. Este ejemplo expone el stock y el precio de los artículos para una tienda online:
page 50100 "CM Item Stock API"
{
PageType = API;
APIPublisher = 'cristianmartinez';
APIGroup = 'shop';
APIVersion = 'v1.0';
EntityName = 'itemStock';
EntitySetName = 'itemStocks';
SourceTable = Item;
ODataKeyFields = SystemId;
Editable = false;
DataAccessIntent = ReadOnly;
layout
{
area(Content)
{
repeater(Records)
{
field(id; Rec.SystemId) { }
field(number; Rec."No.") { }
field(description; Rec.Description) { }
field(unitPrice; Rec."Unit Price") { }
field(inventory; Rec.Inventory) { }
field(lastModifiedDateTime; Rec.SystemModifiedAt) { }
}
}
}
}
Se consulta en .../api/cristianmartinez/shop/v1.0/companies({companyId})/itemStocks. Tres detalles importantes:
ODataKeyFields = SystemId: la clave es un GUID inmutable, como en la API estándar: no cambia aunque alguien renumere el artículo.DataAccessIntent = ReadOnly: las lecturas van a la réplica de solo lectura, cuando está disponible, y no compiten con los usuarios que están trabajando.- La versión en la URL (
v1.0): cuando tengas que cambiar el contrato, publicas unav2.0al lado y no rompes a quien ya consume la primera.
Resumen
- ¿Lo cubre la API v2.0? Úsala.
- ¿Necesitas campos o lógica propios? API propia en una extensión.
- ¿Tienes integraciones sobre páginas de Microsoft publicadas como OData? Revísalas antes de la versión 30.
- Autenticación: OAuth con una aplicación de Entra ID y los permisos justos.
- Diseña pensando en los límites: filtros, sincronización incremental y reintentos.
Si quieres ver cómo encaja todo esto en una integración completa, lo explico en cómo conectar tu web o tienda online con Business Central. Y si necesitas una API propia o revisar una integración antes de la versión 30, hablemos.
