Crear presupuestos

De punta a punta, cómo crear un presupuesto en la compañía correcta, asignarle miembros con sus topes y configurar sus restricciones.

Caso de uso

Un presupuesto define cuánto pueden gastar sus miembros, en qué ciclo se renueva el monto y con qué restricciones (días, horarios, canal y categorías de comercio). Esta receta crea un presupuesto completo en cuatro pasos:

  1. Elegir la compañía.
  2. Crear el presupuesto con POST /budgets.
  3. Agregar los miembros con su tope individual.
  4. Configurar las restricciones.

Si tu API key tiene acceso a varias compañías, presta atención a los avisos de multi-compañía de cada paso (ver también Uso multi-compañía).

1. Elige la compañía

Cada presupuesto pertenece a una compañía, y no se puede cambiar después de crearlo. Obtén el uniqueCode de la compañía con GET /companies, o búscala por su identificación fiscal:

curl -X GET 'https://{HOST}/api/public/v1/companies?taxIdentificationValue=XAXX010101000' \
  -H 'X-API-KEY: tu_api_key_aqui'

Busca también a las personas que van a ser miembros (GET /people) y guarda su uniqueCode.

Multi-compañía: los miembros deben ser de la misma compañía

La API no valida que los miembros pertenezcan a la compañía del presupuesto. Con una key multi-compañía, comprueba que el companyCode de cada persona coincida con la compañía del presupuesto antes de agregarla. Puedes filtrar directamente GET /people?companyCode=<uniqueCode de la compañía>.

2. Crea el presupuesto

curl -X POST 'https://{HOST}/api/public/v1/budgets' \
  -H 'X-API-KEY: tu_api_key_aqui' \
  -H 'Content-Type: application/json' \
  -d '{
    "companyCode": "UNIQUE_CODE_DE_LA_COMPANIA",
    "name": "Viajes comerciales",
    "goal": 50000,
    "cycleType": "RECURRING",
    "startDate": "2026-11-01",
    "expirationDate": "2026-12-31",
    "externalId": "ERP-BUD-0042",
    "members": ["PERSONA_1", "PERSONA_2"]
  }'
CampoObligatorioDetalle
nameSíAl menos 3 caracteres.
goalSíMonto tope, en la moneda de la compañía. En los recurrentes, es el monto de cada ciclo.
cycleTypeSíONE_TIME (no se renueva), RECURRING (se renueva cada mes) o DAY_RECURRING (se renueva cada día).
companyCodeCon key multi-compañíauniqueCode de la compañía. Ver el aviso de abajo.
startDateNoYYYY-MM-DD. Si se omite, rige desde su creación. No puede ser posterior a expirationDate.
expirationDateNoYYYY-MM-DD, inclusive, en la zona horaria de la compañía. Debe ser hoy o una fecha futura.
externalIdNoTu identificador, para relacionarlo con tu sistema.
membersNouniqueCode de las personas. Se agregan sin tope individual.

La respuesta es el presupuesto creado, con su uniqueCode (guárdalo), su companyCode y membersCount. La API responde 200, no 201.

Multi-compañía: de qué depende la compañía del presupuesto

  • Key multi-compañía: companyCode es obligatorio. Sin él, la API responde 400.
  • Key con compañía principal: el presupuesto se crea siempre en esa compañía y el companyCode del body se ignora, aunque indique otra de tus compañías.

En los dos casos, revisa el companyCode de la respuesta para confirmar dónde quedó.

No reintentes a ciegas

POST /budgets no es idempotente: si se corta la conexión y reintentas, puedes crear el presupuesto dos veces. Antes de reintentar, busca con GET /budgets?companyCode=… si ya existe uno con tu externalId o tu name.

3. Agrega los miembros y sus topes

Los miembros de members se agregan sin tope individual. Para asignar un tope por persona, usa POST /budgets/{code}/members:

curl -X POST 'https://{HOST}/api/public/v1/budgets/UNIQUE_CODE_DEL_PRESUPUESTO/members' \
  -H 'X-API-KEY: tu_api_key_aqui' \
  -H 'Content-Type: application/json' \
  -d '[
    { "personCode": "PERSONA_3", "spendLimit": 10000 },
    { "personCode": "PERSONA_4" }
  ]'
  • spendLimit omitido o 0: el miembro comparte el disponible del presupuesto sin tope propio.
  • Es idempotente: si una persona ya es miembro, devuelve su membresía sin cambios y ignora el spendLimit enviado.
  • Los personCode que la API no encuentra se omiten sin error. Compara la respuesta con lo que enviaste para detectar los que no se agregaron.

Para cambiar el tope o bloquear a un miembro existente, usa PATCH /budgets/{code}/members/{memberCode}. memberCode es el uniqueCode de la membresía, no el de la persona. Obtenlo con GET /budgets/{code}/members?personCode=PERSONA_1:

curl -X PATCH 'https://{HOST}/api/public/v1/budgets/UNIQUE_CODE_DEL_PRESUPUESTO/members/UNIQUE_CODE_DE_LA_MEMBRESIA' \
  -H 'X-API-KEY: tu_api_key_aqui' \
  -H 'Content-Type: application/json' \
  -d '[{ "op": "replace", "path": "/spendLimit", "value": 15000 }]'

Solo se admiten los paths /spendLimit y /status (ENABLED o BLOCKED). El tope no puede ser menor a lo que el miembro ya gastó.

4. Configura las restricciones

PUT /budgets/{code}/restrictions reemplaza por completo la configuración: lo que no envíes vuelve a su valor por defecto, y los indicadores booleanos omitidos quedan en false. Envía siempre la configuración completa:

curl -X PUT 'https://{HOST}/api/public/v1/budgets/UNIQUE_CODE_DEL_PRESUPUESTO/restrictions' \
  -H 'X-API-KEY: tu_api_key_aqui' \
  -H 'Content-Type: application/json' \
  -d '{
    "transactionLimit": 5000,
    "daysOfWeekList": [0, 1, 2, 3, 4],
    "startTime": "08:00",
    "endTime": "20:00",
    "onlinePurchaseEnabled": true,
    "physicalPurchaseEnabled": true,
    "localPurchaseEnabled": true,
    "internationalPurchaseEnabled": false,
    "restrictionMode": "INCLUDE",
    "merchantCategories": [{ "categoryUniqueCode": "CODIGO_DE_CATEGORIA" }]
  }'
CampoDetalle
transactionLimitMonto máximo por transacción. Omitido: sin límite.
daysOfWeekListDías habilitados: 0 = lunes … 6 = domingo. Vacío u omitido: todos.
startTime / endTimeHorario habilitado. Omitidos: 00:00 a 23:59:59.
onlinePurchaseEnabled, physicalPurchaseEnabled, localPurchaseEnabled, internationalPurchaseEnabledCanales permitidos. Omitido equivale a false: envía en true cada canal que quieras habilitar.
restrictionModeALL (todas las categorías; merchantCategories vacío), INCLUDE (solo las de la lista) o EXCLUDE (todas menos las de la lista).
merchantCategoriesCategorías de comercio, con su categoryUniqueCode de GET /merchant-categories.

Restricciones que se pierden

Las restricciones por medio de pago configuradas desde la plataforma no se pueden leer ni enviar por esta API, y un PUT las elimina. Si un presupuesto existente las tiene, no le hagas PUT desde la API.

Multi-compañía: categorías de comercio

GET /merchant-categories no admite companyCode. Con una key multi-compañía devuelve el catálogo general, sin las categorías propias que tenga cada compañía. Si necesitas restringir por una categoría propia, consulta con tu contacto de onboarding.

Problemas frecuentes

SíntomaCausa
400 en companyCode al crearTu key es multi-compañía y no enviaste companyCode.
El presupuesto quedó en otra compañíaTu key tiene compañía principal: el companyCode del body se ignora.
400 al crear por fechasexpirationDate ya pasó, o startDate es posterior a expirationDate. Ambas van en YYYY-MM-DD.
La respuesta de miembros trae menos personas que las enviadasAlgún personCode no existe o tu key no puede verlo.
Un miembro no tomó el spendLimitYa era miembro: POST …/members lo ignora. Usa PATCH …/members/{memberCode}.
400 en el PUT de restriccionesrestrictionMode INCLUDE/EXCLUDE sin categorías, o ALL con categorías.
Tras el PUT se rechazan transacciones de un canalOmitiste ese canal: los indicadores omitidos quedan en false.

En esta página