Descripción General
La API Pública de Gastos (Expenses) expone todos los gastos aprobados y enviados por los usuarios de una subsidiaria. Cada gasto contiene los metadatos contables necesarios (centro de costo, categoría, usuario, montos convertidos, documentos) y puede transicionar a los estados accounted o paid para conciliación con tus sistemas externos.
Estados de un Gasto
Internamente un gasto transita por múltiples estados (draft, pending, approved, accounted, paid, rejected).
La API pública solo permite mover un gasto en los siguientes flujos:
approved → accountedapproved → paidaccounted → paid
Endpoints Disponibles
| Método | Endpoint | Descripción |
|---|---|---|
| GET | /public/v1/enterprises/{enterprise_id}/subsidiaries/{subsidiary_id}/expenses/ | Lista de gastos con filtros y paginación. |
| GET | /public/v1/enterprises/{enterprise_id}/subsidiaries/{subsidiary_id}/expenses/{expense_id}/ | Detalle de un gasto. |
| PATCH | /public/v1/enterprises/{enterprise_id}/subsidiaries/{subsidiary_id}/expenses/{expense_id}/ | Actualiza estado (accounted, paid) y campos de tracking externos |
Expand Disponibles
Los campos relacionales pueden expandirse mediante ?expand= (separados por coma). Si no se expanden, se entrega únicamente el ID.
Campo (expand) | Descripción |
|---|---|
cost_center | Datos del centro de costo (id, nombre, internal_id). |
category | Categoría contable asociada. |
user | Usuario rendidor (nombre, contacto, identificadores). |
approved_by | Lista de aprobadores. |
fund | Fondo relacionado (número de fondo, descripción, status). |
fare | Solo para gastos tipo kilometraje. expone la tarifa asociada. |
El campo
additional_file_urlsolo estará presente si la empresa tiene habilitado el add-on de archivos adicionales.
1. Listar Gastos
Endpoint
GET /public/v1/enterprises/{enterprise_id}/subsidiaries/{subsidiary_id}/expenses/
Query Params
| Parámetro | Descripción |
|---|---|
page, page_size | Paginación (por defecto 100 items, máximo 1000). |
state | Filtra por estado interno (pending, approved, accounted, etc.). |
created_at_from | Fecha (YYYY-MM-DD) mínima de creación, inclusive. |
created_at_to | Fecha (YYYY-MM-DD) máxima de creación, inclusive. |
expand | Campos a expandir (ver tabla anterior). |
Respuesta Ejemplo (sin expand)
{
"count": 1,
"next": null,
"previous": null,
"status": 200,
"error": "",
"results": [
{
"id": "4e8b98f4-5719-4316-8142-d3080e476db0",
"description": "Taxi aeropuerto",
"expense_type": "invoice",
"currency": "CLP",
"amount": 45000.0,
"usd_amount": null,
"state": "approved",
"date": "2025-01-12",
"expense_number": 10215,
"content_type": "invoicedata",
"cost_center_id": "6f14a4e4-3513-4a47-9b5f-8a9fba118db7",
"category_id": "3a0c33fe-0fb1-4390-9d32-7005bc30c15f",
"user_id": "bf33075c-cb3b-44e4-9762-b21b16354e74",
"fund_id": null,
"is_active": true,
"created_at": "2025-01-13T14:22:00Z",
"url": "https://storage.googleapis.com/xpendit-expenses/receipt.pdf",
"document_id": "F123",
"expense_document_type": "Factura Afecta",
"provider": "Transporte S.A.",
"payment_method": "credit_card",
"net_amount": 37815.13,
"tax_amount": 7184.87,
"tax_rate": 19.0,
"subsidiary_currency": "CLP",
"subsidiary_expense_amount": 45000.0,
"accounted_id": null,
"paid_id": null,
"paid_at": null
}
]
}
2. Obtener Detalle
Endpoint
GET /public/v1/enterprises/{enterprise_id}/subsidiaries/{subsidiary_id}/expenses/{expense_id}/
Puedes combinar expand para recuperar información enriquecida en una sola llamada:
GET .../expenses/4e8b98f4-5719-4316-8142-d3080e476db0/?expand=cost_center,category,user,fund
Respuesta (con expand)
{
"status": 200,
"error": "",
"id": "4e8b98f4-5719-4316-8142-d3080e476db0",
"description": "Taxi aeropuerto",
"state": "approved",
"cost_center": {
"id": "6f14a4e4-3513-4a47-9b5f-8a9fba118db7",
"name": "Ventas Chile",
"internal_id": "CC-VEN"
},
"category": {
"id": "3a0c33fe-0fb1-4390-9d32-7005bc30c15f",
"name": "Transporte",
"internal_id": "CAT-TRN"
},
"user": {
"id": "bf33075c-cb3b-44e4-9762-b21b16354e74",
"first_name": "Joshua",
"last_name": "Murphy",
"email": "[email protected]",
"phone": "+56912345678",
"internal_id": "EMP-202",
"government_id": "12345678-9"
},
"subsidiary_currency": "CLP",
"subsidiary_expense_amount": 45000.0,
"additional_questions": [],
"created_at": "2025-01-13T14:22:00Z",
"is_active": true
}
3. Actualizar Estado (PATCH)
Usa este endpoint para reflejar en Xpendit que un gasto fue contabilizado o pagado en tus sistemas.
Endpoint
PATCH /public/v1/enterprises/{enterprise_id}/subsidiaries/{subsidiary_id}/expenses/{expense_id}/
Request Body
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
state | string | Sí | accounted o paid. |
accounted_id | string | Opcional | ID de tu sistema contable. Se puede enviar también cuando el nuevo estado es paid. |
paid_id | string | Opcional | ID del pago (solo válido cuando state = paid). |
paid_at | datetime | Opcional | Timestamp ISO8601 del pago (solo válido cuando state = paid). |
Validaciones Relevantes
- Estado actual no puede ser igual al solicitado →
400 Expense is already in {state} state. - Solo
approvedyaccountedpueden moverse → otros estados retornan400 Cannot change state from '{current}'.... paid_idypaid_atse ignoran/validan cuando el estado objetivo no espaid.
Ejemplo: Marcar como Accounted
PATCH /.../expenses/4e8b98f4-5719-4316-8142-d3080e476db0/
Authorization: Api-Key en_sk_xxxxx
Content-Type: application/json
{
"state": "accounted",
"accounted_id": "ACC-EXP-2025-001"
}
Ejemplo: Marcar como Paid
{
"state": "paid",
"accounted_id": "ACC-EXP-2025-001", # Este campo no es necesario al pasar el gasto a pagado
"paid_id": "PAY-EXP-2025-045",
"paid_at": "2025-01-20T15:45:00Z"
}
La respuesta devolverá el gasto actualizado con los nuevos campos de tracking y el estado final.
Códigos de Respuesta
| Código | Motivo |
|---|---|
| 200 | Operación exitosa (GET o PATCH). |
| 400 | Payload inválido, filtros incorrectos o transición no permitida. |
| 403 | API Key inválida o pertenece a otra empresa distinta a la del path. |
| 404 | Gasto inexistente dentro de la subsidiaria especificada. |
Mejores Prácticas
- Paginar siempre para grandes volúmenes; evita
page_sizeenormes si no son necesarios. - Conservar IDs externos (
accounted_id,paid_id) para trazar conciliaciones futuras. - Expand selectivo: solo solicita los campos que necesitas para mantener tiempos de respuesta bajos.
- Fechas en UTC: enviar
paid_atsiempre en formato ISO8601 UTC para evitar problemas de zona horaria.
Con este documento puedes integrar la API pública de gastos en tus procesos contables y de tesorería, manteniendo sincronizados los estados entre tus sistemas y Xpendit.