Desarrolladores
Libros de partida doble: diario, catálogo de cuentas, informes y exportaciones.
GET /books/{companyId}/journal-lines Listar apuntes del libro diarioGET /books/{companyId}/accounts Listar cuentas contablesGET /books/{companyId}/opening-balances Consultar el asiento de aperturaPOST /books/{companyId}/opening-balances Registrar el asiento de aperturaGET /books/{companyId}/consolidation Consultar la consolidación del grupoGET /books/{companyId}/cost-centers/allocations Consultar el reparto por centros de costeGET /books/{companyId}/reports/profit-loss Cuenta de pérdidas y gananciasGET /books/{companyId}/reports/balance-sheet Balance de situaciónGET /books/{companyId}/reports/trial-balance Balance de sumas y saldosGET /books/{companyId}/reports/{report}/export Exportar un informe en CSV, XLSX o PDF/books/{companyId}/journal-linesListar apuntes del libro diario
Apuntes contabilizados (POSTED) del diario en un rango de fechas, paginados y con filtro opcional por prefijo de cuenta. Sin fechas, se usa el trimestre en curso. Los importes son cadenas decimales.
Permiso exigido:
accounting:journal.read (Contabilidad › Libro diario › Leer)
Paginación: Parámetros page y limit. La respuesta incluye total, page, limit, hasMore.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | Id de la empresa. Tiene que estar dentro del alcance del token: la lista está en accountIds de GET /auth/whoami. |
from | query | string (date) | |
to | query | string (date) | |
account | query | string | Filtro por prefijo de cuenta del PGC, p. ej. '400' o '7'. |
page | query | integer | Por defecto: 1 |
limit | query | integer | Por defecto: 100 · máximo: 500 |
200 Apuntes del diario, paginados · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
data | object[] | |
data[].id | string | |
data[].entryDate | string (date) | |
data[].entryNumber | integerpuede ser null | |
data[].period | string | Periodo contable, p. ej. 2026-Q1 |
data[].reference | stringpuede ser null | |
data[].entryDescription | string | |
data[].accountCode | string | |
data[].lineDescription | stringpuede ser null | |
data[].debit | string | Cadena decimal, p. ej. 1234.56 |
data[].credit | string | Cadena decimal, p. ej. 0.00 |
data[].currency | string | |
pagination | object | |
pagination.page | integer | |
pagination.limit | integer | |
pagination.total | integer | |
pagination.hasMore | boolean | |
total | integer | Total de elementos que cumplen el filtro. |
page | integer | Página devuelta (empieza en 1). |
limit | integer | Tamaño de página aplicado. |
hasMore | boolean | Hay más páginas después de esta. |
400 Formato de fecha no válido · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/journal-lines?limit=50" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/journal-lines?limit=50", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/journal-lines?limit=50",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/accountsListar cuentas contables
Catálogo de cuentas con los saldos del periodo ya calculados (netBalance = openingBalance + debitTotal - creditTotal). Los importes son cadenas decimales.
Permiso exigido:
accounting:ledger_accounts.read (Contabilidad › Plan de cuentas › Leer)
Paginación: Parámetros page y limit. La respuesta incluye total, page, limit, hasMore.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
from | query | string (date) | |
to | query | string (date) | |
type | query | string | Valores: asset, liability, equity, income, expense |
active | query | boolean | Por defecto: true |
page | query | integer | Por defecto: 1 |
limit | query | integer | Por defecto: 200 · máximo: 500 |
200 Catálogo de cuentas · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
data | object[] | |
data[].code | string | Código de cuenta del PGC, p. ej. 400 |
data[].name | string | |
data[].type | string | Valores: asset, liability, equity, income, expense |
data[].isActive | boolean | |
data[].openingBalance | string | |
data[].debitTotal | string | |
data[].creditTotal | string | |
data[].netBalance | string | openingBalance + debitTotal - creditTotal |
pagination | object | |
pagination.page | integer | |
pagination.limit | integer | |
pagination.total | integer | |
pagination.hasMore | boolean | |
total | integer | Total de elementos que cumplen el filtro. |
page | integer | Página devuelta (empieza en 1). |
limit | integer | Tamaño de página aplicado. |
hasMore | boolean | Hay más páginas después de esta. |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/accounts?limit=50" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/accounts?limit=50", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/accounts?limit=50",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/opening-balancesConsultar el asiento de apertura
Saldos de apertura por cuenta del ejercicio pedido. Los importes son cadenas decimales.
Permiso exigido:
accounting:opening_balances.read (Contabilidad › Saldos de apertura › Leer)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
year | query | integer |
200 Saldos de apertura
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/opening-balances" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/opening-balances", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/opening-balances",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/opening-balancesRegistrar el asiento de apertura
Permiso exigido:
accounting:opening_balances.create (Contabilidad › Saldos de apertura › Crear)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
replace | query | boolean | Por defecto: false |
application/json| Nombre | Tipo | Descripción |
|---|---|---|
yearobligatorio | integer | |
balancesobligatorio | object[] | |
balances[].accountCode | string | |
balances[].amount | string | Cadena decimal |
200 Saldos de apertura guardados
400 Error de validación · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X POST "https://app.bm.consulting/api/v1/books/<companyId>/opening-balances" \
-H "Authorization: Bearer $BMC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"year":2026,"balances":[{"accountCode":"570","amount":"string"}]}' const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/opening-balances", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"year": 2026,
"balances": [
{
"accountCode": "570",
"amount": "string"
}
]
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.post(
"https://app.bm.consulting/api/v1/books/<companyId>/opening-balances",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
json={
"year": 2026,
"balances": [{
"accountCode": "570",
"amount": "string",
}],
},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/consolidationConsultar la consolidación del grupo
Saldos consolidados de las empresas de la cuenta. Los importes son cadenas decimales.
Permiso exigido:
accounting:reports.read (Contabilidad › Informes (PyG, balance, mayor) › Leer)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
from | query | string (date) | |
to | query | string (date) |
200 Resultado de la consolidación
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/consolidation" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/consolidation", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/consolidation",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/cost-centers/allocationsConsultar el reparto por centros de coste
Reparto por centro de coste, con un resumen. Los importes son cadenas decimales.
Permiso exigido:
accounting:reports.read (Contabilidad › Informes (PyG, balance, mayor) › Leer)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
from | query | string (date) | |
to | query | string (date) |
200 Reparto y resumen
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/cost-centers/allocations" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/cost-centers/allocations", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/cost-centers/allocations",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/reports/profit-lossCuenta de pérdidas y ganancias
Cuenta de pérdidas y ganancias de un periodo. Sin fechas, se usa el trimestre en curso. Los importes son cadenas decimales.
Permiso exigido:
accounting:reports.read (Contabilidad › Informes (PyG, balance, mayor) › Leer)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
from | query | string (date) | |
to | query | string (date) |
200 Cuenta de pérdidas y ganancias · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
companyId | string | |
from | string (date) | |
to | string (date) | |
rows | object[] | |
rows[].accountCode | string | |
rows[].label | string | |
rows[].amount | string | Cadena decimal |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/reports/profit-loss" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/reports/profit-loss", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/reports/profit-loss",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/reports/balance-sheetBalance de situación
Balance de situación (activo y pasivo) de un periodo. Los importes son cadenas decimales.
Permiso exigido:
accounting:reports.read (Contabilidad › Informes (PyG, balance, mayor) › Leer)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
from | query | string (date) | |
to | query | string (date) |
200 Balance de situación · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
companyId | string | |
from | string (date) | |
to | string (date) | |
rows | object[] | |
rows[].accountCode | string | |
rows[].label | string | |
rows[].amount | string | Cadena decimal |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/reports/balance-sheet" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/reports/balance-sheet", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/reports/balance-sheet",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/reports/trial-balanceBalance de sumas y saldos
Balance de sumas y saldos de un periodo. Los importes son cadenas decimales.
Permiso exigido:
accounting:reports.read (Contabilidad › Informes (PyG, balance, mayor) › Leer)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
from | query | string (date) | |
to | query | string (date) |
200 Balance de sumas y saldos · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
companyId | string | |
from | string (date) | |
to | string (date) | |
rows | object[] | |
rows[].accountCode | string | |
rows[].label | string | |
rows[].amount | string | Cadena decimal |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/reports/trial-balance" \
-H "Authorization: Bearer $BMC_TOKEN" const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/reports/trial-balance", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json(); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/reports/trial-balance",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
data = res.json() /books/{companyId}/reports/{report}/exportExportar un informe en CSV, XLSX o PDF
Devuelve el informe elegido como fichero. `report` es uno de `profit-loss`, `balance-sheet`, `trial-balance`, `libro-diario` o `libro-mayor`.
Permiso exigido:
accounting:reports.export (Contabilidad › Informes (PyG, balance, mayor) › Exportar)
Paginación: Sin paginación: devuelve el conjunto completo.
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
companyIdobligatorio | ruta | string | |
reportobligatorio | ruta | string | Valores: profit-loss, balance-sheet, trial-balance, libro-diario, libro-mayor |
formatobligatorio | query | string | Valores: csv, xlsx, pdf |
from | query | string (date) | |
to | query | string (date) |
200 El fichero del informe · text/csv
400 Falta ?format= o no es válido · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
401 Falta el token Bearer o no es válido. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
403 El token no tiene el permiso exigido o el recurso queda fuera de su alcance. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
429 Se ha alcanzado un límite de uso. · application/json
| Nombre | Tipo | Descripción |
|---|---|---|
error | string | Mensaje de error legible |
required_permission | string | Solo en el 403: el permiso que falta (área:recurso.acción) |
curl -X GET "https://app.bm.consulting/api/v1/books/<companyId>/reports/profit-loss/export?format=csv" \
-H "Authorization: Bearer $BMC_TOKEN" \
-o fichero const res = await fetch("https://app.bm.consulting/api/v1/books/<companyId>/reports/profit-loss/export?format=csv", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BMC_TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const file = Buffer.from(await res.arrayBuffer()); import os
import requests
res = requests.get(
"https://app.bm.consulting/api/v1/books/<companyId>/reports/profit-loss/export?format=csv",
headers={"Authorization": f"Bearer {os.environ['BMC_TOKEN']}"},
timeout=30,
)
res.raise_for_status()
contenido = res.content